Pandas按条件拼接两个DataFrame实现逐月跨年同期对比
实现方案
本需求核心为动态匹配去年同期历史行、纵向拼接数据、规整索引顺序,全程无需复杂关联操作,通过固定逻辑流程即可适配所有月份切换场景,完全匹配给出的2021年1月示例输出效果。
分步实现流程
- 配置动态对齐基准月份
将需要对齐的同期月份设置为可传入的参数,避免硬绑定系统时间导致的测试、复用不便。对齐2021年1月同期数据时,设置current_align_month = 1;进入2021年2月时只需将参数值替换为2,后续业务逻辑无需任何修改。 - 筛选历史同期数据子集
基于MultiIndex的层级取值能力,从2020年历史DataFrame中过滤出所有Type下、与基准月份一致的行,自动剔除其余月份的冗余历史数据。核心筛选代码:# 从2020年历史数据中匹配对应当月的所有行 filtered_hist = df_2020[df_2020.index.get_level_values('Date').month == current_align_month] - 纵向拼接数据集
两个DataFrame的列结构、索引层级结构完全一致,直接通过纵向拼接合并内容,不会出现列错位、索引匹配异常的问题:# 纵向拼接筛选后的历史子集和全量2021年新数据 combined_df = pd.concat([filtered_hist, df_2021], axis=0) - 规整索引排序
拼接完成后按Type、Date两个索引层级做升序排序,保证每个Type分组下的日期严格按时间先后排列,和示例输出的顺序完全对齐:# 多级索引排序,固定同一Type下的日期排列顺序 combined_df = combined_df.sort_index(level=['Type', 'Date'])
效果匹配验证
- 当
current_align_month = 1时,筛选得到的历史子集为所有Type对应的2020-01-01行,拼接后每个Type分组下的行顺序为:2020-01-01行 → 2021-01-01行 → 2021-02-01行 → ... → 2021-05-01行,完全复现给出的1月场景示例。 - 当
current_align_month = 2时,筛选逻辑自动提取所有Type对应的2020-02-01行,之前保留的2020-01-01历史行不再出现在结果中,拼接后每个Type分组的行顺序为:2020-02-01行 → 2021年全量日期行,满足2月场景的切换要求。
易踩坑提示
- 不要使用merge类关联操作拼接两个数据集:两个数据集的日期范围无重叠(历史为2020年、新数据为2021年),merge会自动添加列后缀打乱原有列结构,纵向concat是当前场景下适配度最高的拼接方式。
- 不要硬编码固定日期的切片逻辑:比如直接写死取
2020-01-01的行,后续如果扩展到多年历史数据场景,只需调整月份匹配规则即可复用,无需逐行修改硬编码日期值。 - 不要省略拼接后的索引排序步骤:后续如果调整代码执行顺序,sort_index能保证最终索引顺序永远符合“同一Type下日期按时间升序排列”的要求,不会出现历史行排在新数据行后面的顺序错乱问题。
内容的提问来源于stack exchange,提问作者JuniorESE
相关产品推荐
相关产品推荐

