熊猫-分组,汇总和缩放多个列的总和

时间:2018-09-02 06:34:10

标签: python pandas numpy

假设我具有以下DataFrame:

import pandas as pd
df = pd.DataFrame({'id': [1, 2, 2, 3, 3, 3], 'A': [2, 2, 3, 3, 5, 2], 'B': [1, 2, 1, 3, 2, 4]})
df
Out[253]: 
   id  A  B
0   1  2  1
1   2  2  2
2   2  3  1
3   3  3  3
4   3  5  2
5   3  2  4

我想groupby 'id',并在sum'A'上使用'B'函数进行汇总。但是我也想按A+B(每个'id)的总和来缩放A和B,因此以下输出将如下所示:

   id         A         B
0   1  0.666667  0.333333
1   2  0.625000  0.375000
2   3  0.526316  0.473684

现在,我可以做到

res = df.groupby('id').agg('sum').reset_index()
scaler = res['A'] + res['B']
res['A'] /= scaler
res['B'] /= scaler
res
Out[275]: 
   id         A         B
0   1  0.666667  0.333333
1   2  0.625000  0.375000
2   3  0.526316  0.473684

哪个没有意思。有没有办法将所有这些“标量”逻辑放入聚合函数中?还是任何其他Pythonic和优雅的方式做到这一点?也欢迎涉及numpy的解决方案!

3 个答案:

答案 0 :(得分:4)

否,您不能使用agg函数进行缩放,因为要分别处理每列。

解决方案已删除,reset_index是为了对Series创建的sum的{​​{1}}进行除法(div):

res = df.groupby('id').sum()
res = res.div(res.sum(axis=1), axis=0).reset_index()
print (res)
   id         A         B
0   1  0.666667  0.333333
1   2  0.625000  0.375000
2   3  0.526316  0.473684

详细信息:

print (res.sum(axis=1))
id
1     3
2     8
3    19
dtype: int64

答案 1 :(得分:3)

您可以沿第一个轴使用sum

res = df.groupby('id').agg('sum')
res.div(res.sum(1), 0)

           A         B
id
1   0.666667  0.333333
2   0.625000  0.375000
3   0.526316  0.473684

答案 2 :(得分:3)

你可以

In [584]: res = df.groupby('id').sum()

In [585]: res.div(res.sum(1), 0).reset_index()
Out[585]:
   id         A         B
0   1  0.666667  0.333333
1   2  0.625000  0.375000
2   3  0.526316  0.473684