Pandas如何按公共日期列合并两个DataFrame并分组求和
Pandas 按日期匹配求和实现方法
问题场景
现有两个长度不同的Pandas DataFrame:
- 表A为非连续日期的多条数值记录,样例如下:
A = Date Value 0 2022-03-01 50 1 2022-03-01 50 2 2022-03-03 50 3 2022-03-04 50 4 2022-03-04 50 5 2022-03-04 50 6 2022-03-04 50 7 2022-03-04 50 8 2022-03-15 50 9 2022-03-19 50 10 2022-03-23 50
- 表B为连续日期的基准表,样例如下:
B = Value Date Date 2022-03-01 0.0 2022-03-01 2022-03-02 0.0 2022-03-02 2022-03-03 0.0 2022-03-03 2022-03-04 0.0 2022-03-04 2022-03-05 0.0 2022-03-05 2022-03-06 0.0 2022-03-06 2022-03-07 0.0 2022-03-07 2022-03-08 0.0 2022-03-08
需要生成结果表C,规则如下:
- C的日期顺序与B完全一致,仅保留B中存在的日期,A中存在但B未覆盖的日期不纳入
- C中每个日期对应的Value为A中同日期所有Value记录的总和,无匹配记录的日期Value取0
样例预期输出:
C = Value Date 1 100.0 2022-03-01 2 0.0 2022-03-02 3 50.0 2022-03-03 4 250.0 2022-03-04 5 0.0 2022-03-05 6 0.0 2022-03-06 7 0.0 2022-03-07 8 0.0 2022-03-08
原有嵌套循环代码运行失败,且处理真实数据时输出的C所有Value均为0.0,需要正确实现方案。
原有代码问题
- 逻辑错误:内层循环定义的索引变量
n未被使用,日期匹配时两边都取用索引i,无法遍历B的所有行完成匹配;代码中使用==是比较运算而非赋值操作,根本无法向C写入数据;也未实现同日期数值累加的逻辑。 - 真实数据全为0的核心原因:两个表的匹配字段不统一,要么是列名带多余符号(提供的真实数据列名带冒号为
Date:、Value:,和样例列名不一致),要么是Date列数据类型不匹配(一个为字符串、一个为datetime类型),导致匹配时找不到对应记录,所有值都取了默认0。
正确实现代码
Pandas不要用手写for循环做表匹配,用内置的分组聚合+左连接实现,效率高且不易出错:
import pandas as pd # 1. 预处理:统一列名、统一日期类型(解决全0问题的核心步骤) # 清理列名,去掉前后空格、末尾冒号 A.columns = [col.strip().rstrip(':') for col in A.columns] B.columns = [col.strip().rstrip(':') for col in B.columns] # 两个表的Date列统一转为datetime类型 A['Date'] = pd.to_datetime(A['Date']) B['Date'] = pd.to_datetime(B['Date']) # 2. 对A表按日期分组,求和Value A_agg = A.groupby('Date', as_index=False)['Value'].sum() # 3. 以B为基准左连接,匹配不到的值填充0 C = B[['Date']].merge(A_agg, on='Date', how='left').fillna({'Value': 0}) # 如需保留B原有的日期索引,添加下行代码 C = C.set_index(B.index)
异常排查
如果运行后仍存在数值全0的情况,按以下顺序检查:
- 执行
print(A.dtypes, B.dtypes),确认两个表的Date列均为datetime64类型 - 执行
print(A.columns, B.columns),确认列名无多余空格、特殊字符 - 抽取A中存在的任意日期,执行
print(pd.to_datetime('对应日期') in B['Date'].values),确认日期可正常匹配
内容的提问来源于stack exchange,提问作者Djoe
相关产品推荐
相关产品推荐

