pd.concat()垂直合并按行堆叠需设axis=0,注意索引重复和列对齐;水平合并按列拼接需axis=1且索引一致;关联合并应使用merge()而非concat()。

用 pd.concat() 做垂直合并(按行堆叠)
垂直合并就是把多个 DataFrame 上下拼起来,常见于分批读取的日志或报表。核心是设好 axis=0(默认值),但实际用时容易忽略索引重复和列对齐问题。
- 列名不完全一致时,
pd.concat()默认做并集(union),缺失位置填NaN;加参数join='inner'可改成交集(只保留共有的列) - 索引会原样保留,导致重复(比如都是
0, 1, 2),后续.reset_index(drop=True)通常要跟上 - 如果原始 DataFrame 有语义化索引(如日期、ID),建议提前用
ignore_index=False并手动处理索引冲突
df1 = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})
df2 = pd.DataFrame({'A': [5, 6], 'C': [7, 8]})
result = pd.concat([df1, df2], axis=0, join='outer', ignore_index=True)
用 pd.concat() 做水平合并(按列拼接)
水平合并是左右拼,类似 SQL 的 JOIN,但 pd.concat() 不自动对齐行——它只按当前索引位置硬拼。很多人误以为能“按某列关联”,其实不能,那是 merge() 的事。
- 必须确保参与合并的 DataFrame 索引一致,否则会出现错位;可用
df.set_index('key_col')统一索引再 concat -
axis=1是必须显式写的,不能依赖默认值 - 列名重复时会自动加后缀(
_0,_1),可通过suffixes=('_left', '_right')控制
df1 = pd.DataFrame({'A': [1, 2]}, index=['x', 'y'])
df2 = pd.DataFrame({'B': [3, 4]}, index=['x', 'y'])
result = pd.concat([df1, df2], axis=1)
什么时候该用 merge() 而不是 concat()
当你要按某一列(或几列)做关联合并(类似数据库 JOIN),比如“订单表 + 用户表,用 user_id 对齐”,就别碰 concat() —— 它不支持 on、how、left_on/right_on 这些关键参数。
仅使用 Python 将 Claw Code 虚拟化框架与 OpenClaw 集成,提供 184 种工具和 200 多条命令,用于安全分析和代码质量...
-
merge()默认是how='inner',how='left'更常用,避免丢数据 - 两表列名相同时,
on参数最简洁;不同时用left_on和right_on - 性能上,如果 key 列没索引,
merge()会比先 set_index 再concat()慢不少,大数据量建议预处理
orders = pd.DataFrame({'order_id': [101, 102], 'user_id': [1, 2]})
users = pd.DataFrame({'id': [1, 2], 'name': ['Alice', 'Bob']})
merged = pd.merge(orders, users, left_on='user_id', right_on='id', how='left')
合并后列顺序和数据类型容易出问题
concat() 和 merge() 都可能让列顺序变乱,尤其涉及多表、多轮操作时;更隐蔽的是 dtypes 降级——比如某列在部分 DataFrame 中是 int64,另一部分含 NaN,合并后自动变成 float64。
- 合并后立刻检查
result.dtypes,对整数列可用result['col'] = result['col'].astype('Int64')(注意大写 I,支持 NaN) - 列顺序靠
result[['col_a', 'col_b', ...]]显式重排,别依赖输入顺序 - 如果合并结果出现意外
NaN,优先查索引是否对齐、列名是否拼错(大小写、空格)、以及join类型是否选反
实际项目里,合并逻辑一旦超过两层,最好拆成中间变量并加注释——因为 concat 和 merge 的行为差异在调试时很难一眼识别。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










