我有一个如下所示的Pandas DataFrame:
data = {'user_id':[1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 3, 3],
'time':[10, 12, 11, 20, 40, 41, 42, 100, 60, 22, 0, 3],
'height':[1.23, 1.1, 0.5, 10.3, 3.33, 4.55, 2.22, 2.21, 2.25, 7.75, 9.2, 5.5],
'width':[3, 4, 6, 2, 4, 8, 9, 0, 6, 6, 6, 4]}
df = pd.DataFrame(data)
现在,我想从每列(user_id
列除外)中减去按user_id
分组的平均值。也就是说,对于user_id
1,time
的平均值为13.25((10 + 12 + 11 + 20)/ 4),因此从10、12、11和20中减去13.25得出>
'time':[-3.25, -1.25, -2.25, 6.75, 40, 41, 42, 100, 60, 22, 0, 3]
我想对所有列和所有用户执行此操作。该怎么办?
答案 0 :(得分:4)
您可以使用groupby.transform
创建与数据框形状相同的数组。然后从您的time
列中减去该值:
m = df.groupby('user_id')['time'].transform('mean')
df['time'].add(-m)
0 -3.25
1 -1.25
2 -2.25
3 6.75
4 -1.00
5 0.00
6 1.00
7 63.00
8 23.00
9 -15.00
10 -37.00
11 -34.00
Name: time, dtype: float64
m个输出结果为:
print(m)
0 13.25
1 13.25
2 13.25
3 13.25
4 41.00
5 41.00
6 41.00
7 37.00
8 37.00
9 37.00
10 37.00
11 37.00
Name: time, dtype: float64
答案 1 :(得分:3)
这是您想要的吗?
df[df.columns.difference(['user_id'])].sub(df.groupby('user_id').transform('mean'))
来自@piRSquare:
df.update(df - df.groupby('user_id').transform('mean'))
或
df.loc[:, ['height', 'time', 'width']] -= df.groupby('user_id').transform('mean')
来自@ anky_91:
df.drop('user_id',1).sub(df.groupby('user_id').time.transform('mean'),axis=0)
Out[2054]:
height time width
0 -2.052500 -3.25 -0.75
1 -2.182500 -1.25 0.25
2 -2.782500 -2.25 2.25
3 7.017500 6.75 -1.75
4 -0.036667 -1.00 -3.00
5 1.183333 0.00 1.00
6 -1.146667 1.00 2.00
7 -3.172000 63.00 -4.40
8 -3.132000 23.00 1.60
9 2.368000 -15.00 1.60
10 3.818000 -37.00 1.60
11 0.118000 -34.00 -0.40