熊猫条件组由和和

时间:2018-02-20 14:26:32

标签: python pandas group-by sum

有没有办法可以对一个DataFrame的某些行进行groupby和sum,但其余部分保留原样?例如,我有df:

df = pd.DataFrame({
'A' : ['foo', 'bar', 'foo', 'bar', 'foo', 'bar', 'foo', 'foo'],
'B' : ['one', 'one', 'two', 'three', 'two', 'two', 'one', 'three'],
'C' : np.random.randn(8),
'D' : np.random.randn(8)})

看起来像:

     A      B         C         D
0  foo    one  0.469112 -0.861849
1  bar    one -0.282863 -2.104569
2  foo    two -1.509059 -0.494929
3  bar  three -1.135632  1.071804
4  foo    two  1.212112  0.721555
5  bar    two -0.173215 -0.706771
6  foo    one  0.119209 -1.039575
7  foo  three -1.044236  0.271860

现在我想将B中的值为one的行进行分组/求和(并将最后一次出现在A列中)。所以输出将是:

     A      B      sumC      sumD
1  foo    two -1.509059 -0.494929
2  bar  three -1.135632  1.071804
3  foo    two  1.212112  0.721555
4  bar    two -0.173215 -0.706771
5  foo    one  0.030545 -4.005993
6  foo  three -1.044236  0.271860

如何做到这一点?

2 个答案:

答案 0 :(得分:1)

让我们使用它:

pd.concat([df.query('B != "one"'),
           df.query('B == "one"').groupby('B', as_index=False)['A','C','D']
             .agg({'A':'last','C':'sum','D':'sum'})])

输出:

     A      B         C         D
2  foo    two  0.656942 -0.605847
3  bar  three  1.022090  0.493374
4  foo    two -1.016595  0.652162
5  bar    two -0.738758 -0.669947
7  foo  three  0.913342  1.156044
0  foo    one  0.590764 -0.192638

答案 1 :(得分:0)

另一种解决方法是定义一个新的列,如果-1B则为常量(例如one),否则为唯一值(例如范围)就此而言。

df['B2'] = np.where(df['B']=='one', -1, np.arange(len(df)))
df.groupby('B2', as_index=False).agg({'A': 'last', 'B': 'max', 'C': 'sum', 'D': 'sum'}).drop('B2', axis=1)

这可以避免进行最终丢弃的计算(尽管如果你真的想要避免这些事情,最简单的方法就是将你的DataFrame分成两部分,其中df.B == 'one'和{{1}只能在前者上工作,然后将结果连接起来)