Pandas按多个列分组并使用多个自定义聚合函数

3
给定数据:
grp data1 data2 data3
a 2 1 2
a 4 6 3
b 3 2 1
b 7 3 5
期望输出:
grp sum(data1) sum(data2)/sum(data1) sum(data3)/sum(data1)
a 6 1.166666667 0.83
b 10 0.4 0.4
假设自定义聚合可以依赖于多列,并不总是一个简单的除法操作。虽然用SQL查询是可能的,但如果可能,我更感兴趣的是使用apply和aggregate函数的答案。
2个回答

2
您可以这样做:
df2 = df.groupby('grp').sum()
df2.update(df2.drop(columns='data1').div(df2['data1'], axis=0))

更经典的说法是:
df2 = df.groupby('grp').sum()
df2[['data2', 'data3']] = df2[['data2', 'data3']].div(df2['data1'], axis=0)

输出:

     data1     data2     data3
grp                           
a        6  1.166667  0.833333
b       10  0.500000  0.600000
多重聚合

您可以使用相同的逻辑来处理MultiIndex:

df2 = df.groupby('grp').agg(['sum', 'mean'])
df2.update(df2.drop(columns='data1').stack(0).div(df2['data1'], axis=0).unstack())

输出:

    data1      data2      data3     
      sum mean   sum mean   sum mean
grp                                 
a       6  3.0     7  3.5     5  2.5
b      10  5.0     5  2.5     6  3.0

如果我还想使用其他聚合函数,比如平均值怎么办?你在这里使用了所有列的总和,但通常我不需要这样做。例如:sum(data1),avg(data2),min(data2),sum(data2)/sum(data1)等。 - Parshant garg
请检查上面的评论。@mozway - Parshant garg
@Parshantgarg,这对你有用吗? - mozway

2
你可以使用groupby + assign来生成所需的聚合。你可以应用任何所需的聚合函数。
g = df.groupby('grp')
#                                         for custom agg func use .agg(custom_agg_func)
#                                                          ^^^^^
g[['data1']].agg('sum').assign(sum2 = lambda df: g['data2'].sum()/df['data1'],
                               sum3 = lambda df: g['data3'].sum()/df['data1'])
#                ^^^^^^
#    you can use custom agg func of your choice

     data1      sum2      sum3
grp                           
a        6  1.166667  0.833333
b       10  0.500000  0.600000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接