在 pandas groupby 之后合并 idx 和 agg 结果

combining idx and agg results after a pandas groupby

我正在 keyAgg 上的 Ds 数据帧内聚合 tgt: 我可以轻松总结

Ds.groupby(Ds.keyAgg).tgt.agg([sum])

并导出每个组的 tgt 中最小值的索引。

Ds.groupby(Ds.keyAgg).tgt.idxmin()

有没有一种干净的方法来组合这两个操作,而不需要两个中间结果的昂贵 pd.merge()

我认为你可以将聚合函数列表传递给 GroupBy.agg 如果两个 return 聚合值:

Ds = pd.DataFrame({'keyAgg':[1,1,2,2,3,3,3],
                   'tgt':   [4,8,2,0,4,5,1]})
print (Ds)
   keyAgg  tgt
0       1    4
1       1    8
2       2    2
3       2    0
4       3    4
5       3    5
6       3    1

df = Ds.groupby('keyAgg').tgt.agg(['sum', 'idxmin'])
print (df)
        sum  idxmin
keyAgg             
1        12       0
2         2       3
3        10       6

但如果不像cumsum那就是问题:

df = Ds.groupby('keyAgg').tgt.agg(['sum', 'cumsum'])
print (df)
    sum  cumsum
0   NaN       4
1  12.0      12
2   2.0       2
3  10.0       2
4   NaN       4
5   NaN       9
6   NaN      10

那么一种可能的解决方案是使用自定义函数:

def func(x):
    a = x.sum()
    b = x.cumsum()

    return pd.DataFrame({'sum':a, 'cumsum':b})

Ds[['sum','cum']] = Ds.groupby('keyAgg').tgt.apply(func)
print (Ds)
   keyAgg  tgt  sum  cum
0       1    4   12    4
1       1    8   12   12
2       2    2    2    2
3       2    0    2    2
4       3    4   10    4
5       3    5   10    9
6       3    1   10   10

或使用 transform 调用聚合函数并最后连接在一起:

df = pd.concat([Ds.groupby('keyAgg').tgt.transform('sum'),
                Ds.groupby('keyAgg').tgt.cumsum()], axis=1, keys=('sum','cum'))
print (df)
   sum  cum
0   12    4
1   12   12
2    2    2
3    2    2
4   10    4
5   10    9
6   10   10