
本文介绍如何使用 pd.merge() 按索引对齐合并两个行数不等的 DataFrame,实现“宽合并”(side-by-side),结果行数为二者最大值,缺失位置自动填充 NaN。
本文介绍如何使用 `pd.merge()` 按索引对齐合并两个行数不等的 dataframe,实现“宽合并”(side-by-side),结果行数为二者最大值,缺失位置自动填充 nan。
在实际数据处理中,常遇到需将两个结构不同、长度不一的 DataFrame 进行横向拼接(如分别来自不同 Excel 表的工时记录与物料清单),且要求它们从同一行索引(如 index=0)开始对齐,而非简单纵向堆叠或按默认 concat(axis=1) 的“截断式”对齐(即以最短 DataFrame 行数为准)。此时,pd.concat(..., axis=1) 默认行为会因索引不匹配导致错位或截断;而 pd.merge() 配合 how='outer' 与索引键匹配,则能精准实现“最长对齐 + 缺失补 NaN”的目标。
✅ 正确做法是:使用 pd.merge(),以左右 DataFrame 的行索引(left_index=True, right_index=True)作为连接键,并指定 how='outer'。这等价于基于索引的全外连接,确保结果包含所有索引位置(0, 1, 2, …, max(len(df1), len(df2))−1),对应位置无数据处自动填充 NaN。
示例代码如下:
import pandas as pd
# 构造示例数据(模拟原始问题中的 df1 和 df2)
df1 = pd.DataFrame({'A': [1, 3], 'B': [2, 4]}) # 2 行
df2 = pd.DataFrame({'C': [5, 7, 9], 'D': [6, 8, 10]}) # 3 行
# ✅ 按索引外连接:结果为 3 行,df1 的第 2 行(index=2)自动补 NaN
result = pd.merge(df1, df2, left_index=True, right_index=True, how='outer')
print(result)
输出:
A B C D 0 1.0 2.0 5 6.0 1 3.0 4.0 7 8.0 2 NaN NaN 9 10.0
⚠️ 注意事项:
- 不要使用
pd.concat([df1, df2], axis=1)直接拼接——它默认join='outer',看似可行,但当输入 DataFrame 索引非连续整数(如含跳号、字符串索引)时,行为不可控;而merge显式声明索引连接,语义更清晰、鲁棒性更强。 - 若原始数据索引已被重置或不规整,建议先统一调用
.reset_index(drop=True)确保双方均为标准整数索引(0, 1, 2…)。 -
how='outer'是关键:'inner'仅保留共有的索引(取最小长度),'left'/'right'则以某一方为主,均不符合“结果长度为max(len(df1), len(df2))”的要求。 - 对于你原始脚本中动态分块场景,可在每个
block_df与对应filtered_df合并时直接替换为该merge写法,无需手动构造空列表或临时 DataFrame。
总结:pd.merge(df1, df2, left_index=True, right_index=True, how='outer') 是解决“等长对齐横向拼接”问题的简洁、可靠、可读性强的标准方案,推荐作为此类需求的首选方法。










