Pandas按条件进行groupby.agg

3

我有一个类似于这样的pandas数据框:

姓名 销售额 利润 利润标志
200 100
300 150
马克 200 100
马克 300 150
朱迪 300 150

实际数据框有100列。

这个想法是:我想按名称分组,并聚合所有列。但是,某些列取决于一个标志。在这种情况下,无论如何都将聚合sales,但只有当profit_flagTrue时才应包括在聚合中。

如果我们使用sum,它应该看起来像这样:

名称 销售额 利润
500 100
朱迪 300 Nan
马克 500 250

有没有办法可以使用df.groupby('name').agg()一行代码完成?

目前我正在使用:

grouped = pd.DataFrame()
grouped['sales'] = df.groupby('name').sales.sum()
grouped['profit'] = df[df.profit_flag].groupby('name').profit.sum()

我得到了正确的结果,但由于实际数据框有更多的列,我想知道是否可以写出像这样的东西来避免混乱:
grouped = df.groupby('name').agg({
          'sales': 'sum',
          'profit' 'sum' #if profit_flag })

这个可行吗,还是我应该将“标志依赖列”分组在单独的语句中?

1个回答

4

在聚合之前,您可以掩盖这些值:

(df.assign(profit=lambda d: d['profit'].where(d['profit_flag']))
   .groupby('name', as_index=False)[['sales', 'profit']].sum(min_count=1)
)

输出:

   name  sales  profit
0   Joe    500   100.0
1  Judy    300     NaN
2  Mark    500   250.0

你可以在不选择列的情况下,使用 pop('profit_flag')df.assign(profit=lambda x: x['profit'].where(x.pop('profit_flag'))).groupby('name').sum(min_count=1) - Corralien
好的,我明白了。但在这种情况下,您不需要使用 lambdadf.assign(profit=df['profit'].where(df['profit_flag'])).groupby('name', as_index=False)[['sales', 'profit']].sum(min_count=1)。为什么要重新评估数据框呢? - Corralien
也许这是真的,但养成好习惯从来不会有坏处 ;) - mozway
谢谢!我可能会在一个语句中分配所有基于标志的列,然后使用.agg在另一个语句中聚合所有列。 - Samba
2
使用.assign(**{'name with %': ...}) - mozway
显示剩余2条评论

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