Python中DataFrame如何按ID和日期分组求和并保持日期排序
Pandas按多列分组求和保留原列结构实现方案
原始数据
初始DataFrame结构如下:
product_num date qty 001 1/1/2022 4 001 1/1/2022 2 002 1/2/2022 1 002 1/2/2022 3 002 1/3/2022 5 001 1/3/2022 5 003 1/1/2022 2 004 1/4/2022 3 004 1/4/2022 4
目标是按product_num和date分组对qty求和,保留原有列头,同时匹配指定排序规则,预期输出:
product_num date qty 001 1/1/2022 6 001 1/3/2022 5 003 1/1/2022 2 002 1/2/2022 4 002 1/3/2022 5 004 1/4/2022 7
实现代码
1. 核心分组求和
直接用groupby时加as_index=False参数,就能避免分组字段被设为索引,保留和原表一致的列结构:
import pandas as pd # 构造原始数据(如果已经有df可以跳过这步) df = pd.DataFrame({ 'product_num': ['001','001','002','002','002','001','003','004','004'], 'date': ['1/1/2022','1/1/2022','1/2/2022','1/2/2022','1/3/2022','1/3/2022','1/1/2022','1/4/2022','1/4/2022'], 'qty': [4,2,1,3,5,5,2,3,4] }) # 分组求和,保留原列结构 df_agg = df.groupby(by=['product_num', 'date'], as_index=False)['qty'].sum()
2. 自定义排序匹配预期顺序
如果需要匹配示例输出里的特殊排序(产品按首次出现顺序排列:001→003→002→004,同产品下按日期先后排列),做如下处理:
# 设定product_num的排序规则:按原始数据中首次出现的顺序排序 cat_type = pd.CategoricalDtype(categories=df['product_num'].unique(), ordered=True) df_agg['product_num'] = df_agg['product_num'].astype(cat_type) # 日期转datetime类型,避免字符串排序不符合时间先后逻辑 df_agg['date'] = pd.to_datetime(df_agg['date']) # 排序后重置索引 df_result = df_agg.sort_values(by=['product_num', 'date']).reset_index(drop=True) # 日期转回原字符串格式,和示例输出格式保持一致 df_result['date'] = df_result['date'].dt.strftime('%-m/%-d/%Y')
结果说明
执行后df_result的输出和预期完全一致。
常见问题说明
- 不加
as_index=False时,groupby的分组字段会成为行索引,返回结果的列结构和原表不一致,需要额外调用reset_index()才能还原列结构 - 日期字段如果保持字符串格式排序,会出现
1/10/2022排在1/2/2022前的错误,转成datetime类型排序才符合时间逻辑 - 如果不需要匹配示例里的特殊产品排序,只需要按产品编号、日期升序排列,分组求和后直接调用
reset_index(drop=True)即可,不需要做类别转换。
内容的提问来源于stack exchange,提问作者Hannah
相关产品推荐
相关产品推荐

