【问题标题】:pandas groupby apply on multiple columns to generate a new columnpandas groupby 应用于多个列以生成新列
【发布时间】:2018-04-23 22:45:36
【问题描述】:

我喜欢使用 groupby-apply 在 pandas 数据框中生成一个新列。

例如,我有一个数据框:

df = pd.DataFrame({'A':[1,2,3,4],'B':['A','B','A','B'],'C':[0,0,1,1]})

并尝试通过 groupby-apply 生成一个新列“D”。

这行得通:

df = df.assign(D=df.groupby('B').C.apply(lambda x: x - x.mean()))

因为(我认为)它返回与数据框具有相同索引的系列:

In [4]: df.groupby('B').C.apply(lambda x: x - x.mean())
Out[4]:
0   -0.5
1   -0.5
2    0.5
3    0.5
Name: C, dtype: float64

但如果我尝试使用多列生成新列,我无法将其直接分配给新列。所以这不起作用:

 df.assign(D=df.groupby('B').apply(lambda x: x.A - x.C.mean()))

返回

TypeError: incompatible index of inserted column with frame index

事实上,groupby-apply 返回:

In [8]: df.groupby('B').apply(lambda x: x.A - x.C.mean())
Out[8]:
B
A  0    0.5
   2    2.5
B  1    1.5
   3    3.5
Name: A, dtype: float64

我可以的

df.groupby('B').apply(lambda x: x.A - x.C.mean()).reset_index(level=0,drop=True))

但这似乎很冗长,我不确定这是否会一直按预期工作。

所以我的问题是:(i)pandas groupby-apply 什么时候返回类似索引系列与多索引系列? (ii) 有没有更好的方法通过 groupby-apply 将新列分配给多个列?

【问题讨论】:

    标签: python pandas pandas-groupby pandas-apply


    【解决方案1】:

    让我们在 groupby 中使用group_keys=False

    df.assign(D=df.groupby('B', group_keys=False).apply(lambda x: x.A - x.C.mean()))
    

    输出:

       A  B  C    D
    0  1  A  0  0.5
    1  2  B  0  1.5
    2  3  A  1  2.5
    3  4  B  1  3.5
    

    【讨论】:

    • 这直接回答了我的问题。
    • 请注意,此解决方案仅在 .apply() 方法返回与您分配的数据框具有相同行数的系列时才有效。否则返回的系列的索引和数据框不匹配。
    • @petrovski 感谢您指出这一点,我想知道这样的事情会如何工作
    【解决方案2】:

    对于这种情况,我认为不需要在 apply 中包含 A 列,我们可以使用 transform

    df.A-df.groupby('B').C.transform('mean')
    Out[272]: 
    0    0.5
    1    1.5
    2    2.5
    3    3.5
    dtype: float64
    

    你可以把它分配回去

    df['diff']= df.A-df.groupby('B').C.transform('mean')
    df
    Out[274]: 
       A  B  C  diff
    0  1  A  0   0.5
    1  2  B  0   1.5
    2  3  A  1   2.5
    3  4  B  1   3.5
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2022-11-23
      • 2019-07-02
      • 1970-01-01
      • 2022-01-16
      • 1970-01-01
      • 2013-01-09
      相关资源
      最近更新 更多