有没有办法可以对一个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
如何做到这一点?
答案 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)
另一种解决方法是定义一个新的列,如果-1
为B
则为常量(例如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}只能在前者上工作,然后将结果连接起来)