Pandas在groupby中返回空组

Oli*_*ain 6 python pandas

我有一个数据帧的熊猫3列,target,pred,和conf_bin.如果我运行了一个groupby(by='conf_bin').apply(...)我的应用函数,则会使用空DataFrames来调用未出现在conf_bin列中的值.这怎么可能?


细节

DataFrame看起来像这样:

        target  pred conf_bin
0            5     6     0.50
1            4     4     0.60
2            4     4     0.50
3            4     3     0.50
4            4     5     0.50
5            5     5     0.55
6            5     5     0.55
7            5     5     0.55
Run Code Online (Sandbox Code Playgroud)

显然conf_bin是一个数值区域,其值在该范围内np.arange(0, 1, 0.05).但是,并非所有值都存在于数据中:

In [224]: grp = tp.groupby(by='conf_bin')

In [225]: grp.groups.keys()
Out[225]: dict_keys([0.5, 0.60000000000000009, 0.35000000000000003, 0.75, 0.85000000000000009, 0.65000000000000002, 0.55000000000000004, 0.80000000000000004, 0.20000000000000001, 0.45000000000000001, 0.40000000000000002, 0.30000000000000004, 0.70000000000000007, 0.25])
Run Code Online (Sandbox Code Playgroud)

因此,例如,值00.05没有出现.但是,当我apply在组上运行时,我的函数会调用这些值:

In [226]: grp.apply(lambda x: x.shape)
Out[226]:
conf_bin
0.00        (0, 3)
0.05        (0, 3)
0.10        (0, 3)
0.15        (0, 3)
0.20       (22, 3)
0.25       (75, 3)
0.30       (95, 3)
0.35      (870, 3)
0.40     (8505, 3)
0.45    (40068, 3)
0.50    (51238, 3)
0.55    (54305, 3)
0.60    (47191, 3)
0.65    (38977, 3)
0.70    (34444, 3)
0.75    (20435, 3)
0.80     (3352, 3)
0.85        (4, 3)
0.90        (0, 3)
dtype: object
Run Code Online (Sandbox Code Playgroud)

问题:

  1. Pandas怎么能知道值0.0和0.5"有意义",因为它们没有出现在我的身上DataFrame
  2. 为什么DataFrame对于没有出现的值调用我的apply函数和空对象grp.groups

Fra*_*anc 2

我也遇到了这个问题,当我尝试为数据框中的每个类别创建子图时,就会出现这个问题。

我想出了以下解决方法(基于这篇 SO post),将非空组拉到列表中。

groups = df.groupby('conf_bin')
group_list = [(index, group) for index, group in groups if len(group) > 0]
Run Code Online (Sandbox Code Playgroud)

它确实打破了“你在 pandas 中争论数据”的隐含契约,并且可能对内存管理不善,但它确实有效。


现在您可以使用与 groupby 对象相同的接口迭代 groupby 列表,例如

fig, axes = plt.subplots(nrows=len(group_list), ncols=1)
for (index, group), ax in zip(group_list, axes.flatten()):
    group['target'].plot(ax=ax, title=index)
Run Code Online (Sandbox Code Playgroud)