在不使用for循环的情况下从个体中减去子组均值

9 投票
1 回答
3986 浏览
提问于 2025-04-18 13:00

我有一个数据表,里面有很多列,其中有两列是用来分组的变量。

>>> 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

我想创建一个新的数据表,这个新表里记录的是原始数据表中每个数据点与其所在子组的平均值之间的差。

首先,我会先用分组的平均值来创建这个新表:

>>> 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

在这个新数据表中,我想保留这些差值,定义为:

差值 = 个人数值 - 这个个人所属子组的平均值

现在,我知道怎么用比较繁琐的方法(比如用循环)来做到这一点,但我想应该有更简单优雅的解决办法。如果有人能给我一些建议,帮助我找到这个更优雅的解决方案,我会非常感激。谢谢!

1 个回答

14

使用 .groupby(...).transform 函数:

>>> demean = lambda df: df - df.mean()
>>> df.groupby(['Groupvar1', 'Groupvar2']).transform(demean)

然后用 pd.concat 把结果和原始的数据框合并在一起。

撰写回答