从个体中减去子组平均值而不求助于循环

Cha*_*e_M 8 python vectorization pandas

我有一个包含多个列的数据框,其中两列是分组变量.

>>> df2
   Groupvar1  Groupvar2         x         y         z
0          A          1  0.726317  0.574514  0.700475
1          A          2  0.422089  0.798931  0.191157
2          A          3  0.888318  0.658061  0.686496
....
13         B          2  0.978920  0.764266  0.673941
14         B          3  0.759589  0.162488  0.698958
Run Code Online (Sandbox Code Playgroud)

我想创建一个新的数据帧,它保存origianl df中每个数据点与对应于其子组的平均值之间的差异.

所以首先使用分组平均值制作新的df:

>>> grp_vars = ['Groupvar1','Groupvar2']
>>> df2_grp = df2.groupby(grp_vars)
>>> df2_grp_avg = df2_grp.mean()
>>> df2_grp_avg
                            x         y         z
Groupvar1 Groupvar2                              
A         1          0.364533  0.645237  0.886286
          2          0.325533  0.500077  0.246287
          3          0.796326  0.496950  0.510085
          4          0.774854  0.688732  0.487547
B         1          0.743783  0.452482  0.612006
          2          0.575687  0.396902  0.446126
          3          0.473152  0.476379  0.508060
          4          0.434320  0.406458  0.382187
Run Code Online (Sandbox Code Playgroud)

在新的dtaframe中我想保留增量,定义为:

delta =个人值 - 此个人所属的子组的平均值

现在,我很清楚如何以艰难的方式(循环)这样做,但我想必须有一个更优雅的解决方案.建议寻找更优雅的解决方案.TIA.

beh*_*uri 12

使用.groupby(...).transform功能:

>>> demean = lambda df: df - df.mean()
>>> df.groupby(['Groupvar1', 'Groupvar2']).transform(demean)
Run Code Online (Sandbox Code Playgroud)

蚂蚁然后pd.concat结果与原始数据框架.

  • 仅供参考,在0.14.1中它现在要快得多:df-df.groupby(...).transform('mean') (2认同)