Pandas按特定列分组并求和
下面是一个简单的例子,展示了我遇到的问题。我们初始的状态如下(我只是用字典来演示):
A = [{'D': '16.5.2013', 'A':1, 'B': 0.0, 'C': 2}, {'D': '16.5.2013', 'A':1, 'B': 0.0, 'C': 4}, {'D': '16.5.2013', 'A':1, 'B': 0.5, 'C': 7}]
df = pd.DataFrame(A)
>>> df
A B C D
0 1 0.0 2 16.5.2013
1 1 0.0 4 16.5.2013
2 1 0.5 7 16.5.2013
我想知道如何从 df 转换到 df_new,结果是:
A_new = [{'D': '16.5.2013', 'A':1, 'B': 0.0, 'C': 6}, {'D': '16.5.2013', 'A':1, 'B': 0.5, 'C': 7}]
df_new = pd.DataFrame(A_new)
>>> df_new
A B C D
0 1 0.0 6 16.5.2013
1 1 0.5 7 16.5.2013
因为 'B' 列的值在前两行是相同的,所以 'C' 列的前两行会被加在一起。其他的列保持不变,比如 'A' 列不进行求和,'D' 列也不变。我该怎么做,假设我只有 df,想要得到 df_new。如果能找到一种优雅的解决方案,我会非常感激。
提前谢谢大家。
2 个回答
2
假设其他列的数据总是相同的,不需要特别处理。
首先,创建一个新的数据框 df_new
,按照 B
列进行分组,在每个组中取每一列的第一行数据:
In [17]: df_new = df.groupby('B', as_index=False).first()
然后,专门对 C
列进行计算,求出每个组的总和:
In [18]: df_new['C'] = df.groupby('B', as_index=False)['C'].sum()['C']
In [19]: df_new
Out[19]:
B A C D
0 0.0 1 6 16.5.2013
1 0.5 1 7 16.5.2013
如果你的列数不多,也可以一步到位(不过如果列数多的话,上面的方式会更方便,不用手动处理太多),可以为每一列指定想要的计算方法:
In [20]: df_new = df.groupby('B', as_index=False).agg({'A':'first', 'C':'sum', 'D':'first'})
0
如果A和D在按B分组时总是相等,那么你可以只按A、B和D分组,然后对C进行求和:
df.groupby(['A', 'B', 'D'], as_index = False).agg(sum)
输出结果:
A B D C
0 1 0.0 16.5.2013 6
1 1 0.5 16.5.2013 7
另外:
你其实是想要把数据按B这一列进行汇总。要对C这一列进行汇总,你只需要使用内置的sum
函数。对于其他列,你基本上只想选择一个值,因为你认为它们在每个组内总是相同。为此,只需写一个非常简单的函数,通过取第一个值来汇总这些列。
# will take first value of the grouped data
sole_value = lambda x : list(x)[0]
#dictionary that maps columns to aggregation functions
agg_funcs = {'A' : sole_value, 'C' : sum, 'D' : sole_value}
#group and aggregate
df.groupby('B', as_index = False).agg(agg_funcs)
输出结果:
B A C D
0 0.0 1 6 16.5.2013
1 0.5 1 7 16.5.2013
当然,你需要确保A和D这两列的值确实是相等的,否则你可能会保留错误的数据。