首页 > 解决方案 > pandas lambda 函数返回 df 和 series,为什么?

问题描述

给定一个df和一个lambda函数:

df = pd.DataFrame({'label' : ['a', 'a', 'a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c'],
                  't' :      [1, 2, 3, 4, 5, 1, 2, 3, 4, 1, 2, ],
                  'x' : [48,  6, 30, 30, 53, 48, 25, 51,  9, 55, 2]})
top3 = lambda x : x.groupby('t')['x'].idxmax().head(3)

我尝试了几种组合label并在调用该函数时得到了不同的结果:

print(df.groupby('label').apply(top3))

label  t
a      1     0
       2     1
       3     2
b      1     5
       2     6
       3     7
c      1     9
       2    10
Name: x, dtype: int64


df2 = df[df.label=='a']
print(df2.groupby('label').apply(top3))

t      1  2  3
label         
a      0  1  2


df3 = df[df.label.isin(['a', 'b'])]
print(df3.groupby('label').apply(top3))
t      1  2  3
label         
a      0  1  2
b      5  6  7

第一个结果是一个系列,而接下来的两个是数据帧。为什么会这样?

标签: pythonpandas

解决方案


.groupby.apply()它背后有很多魔力,试图强迫事物成为它认为最好的形状。当c从传递的数据帧中排除时,它可以将事物强制转换为一个干净的矩形数据帧,但c如果包含,它将回退到 MultiIndex:

In [71]: df[df.label.isin(['a', 'c'])].groupby('label').apply(top3)
Out[71]:
label  t
a      1     0
       2     1
       3     2
c      1     9
       2    10
Name: x, dtype: int64

如果你想跟踪pandas'代码中的兔子洞,你可以从这里开始:https ://github.com/pandas-dev/pandas/blob/30362ed828bebdd58d4f1f74d70236d32547d52a/pandas/core/groupby/ops.py#L189


推荐阅读