如何在 Pandas 中基于公共列的并集横向合并多个 DataFrame
本文介绍使用 pd.concat() 沿列方向(axis=1)合并多个 dataframe 的标准方法:先重命名列避免冲突,再以公共键(如 id)为索引对齐,自动实现全外连接效果,生成带层级或前缀的宽表结构。 在数据处理中,把多个表按一个公共列“横向拼起来”是个高频场景。比如,不同来源的数据都是以
本文介绍使用 pd.concat() 沿列方向(axis=1)合并多个 dataframe 的标准方法:先重命名列避免冲突,再以公共键(如 id)为索引对齐,自动实现全外连接效果,生成带层级或前缀的宽表结构。
在数据处理中,把多个表按一个公共列“横向拼起来”是个高频场景。比如,不同来源的数据都是以 id 为键,但字段各不相同,你想把它们合并成一个宽表,保留所有 id,没有的字段就留空——这其实就是 SQL 里的 FULL OUTER JOIN。
很多人第一反应是用 pd.merge(),但默认的 merge 是按交集对齐,要做全外连接还得额外加参数,而且多个表合并时代码会变得很啰嗦。其实,有更简洁的方式:用 pd.concat() 配合索引对齐。
核心思路就三步:
- 给每个 DataFrame 的列加上前缀,比如
df1_、df2_,避免列名冲突; - 把公共键列设为索引,比如
set_index("id"),这样 pandas 就能基于索引值来对齐行; - 沿列方向拼接:
pd.concat([df1_idx, df2_idx], axis=1),pandas 会自动执行全外连接(并集),缺失位置填 NaN。
来个完整的例子,一看就明白:
import pandas as pd
# 构造原始数据
df1 = pd.DataFrame({"id": [1, 2, 4], "name": ["a", "b", "c"], "val": [23, 90, 72]})
df2 = pd.DataFrame({"id": [1, 3, 4], "name": ["d", "e", "f"], "val": [88, 12, 11]})
# 步骤1:添加前缀并重命名列
df1 = df1.add_prefix("df1_")
df2 = df2.add_prefix("df2_")
# 步骤2:以 id 列为索引
df1_idx = df1.set_index("df1_id")
df2_idx = df2.set_index("df2_id")
# 步骤3:横向拼接(自动对齐索引)
result = pd.concat([df1_idx, df2_idx], axis=1)
print(result)
输出结果长这样:
df1_name df1_val df2_name df2_val 1 a 23.0 d 88.0 2 b 90.0 NaN NaN 3 NaN NaN e 12.0 4 c 72.0 f 11.0
看,索引 1 和 4 都有数据,2 和 3 则各自缺失了一部分,自动补了 NaN。
✅ 几个关键点值得注意:
- 索引对齐是核心机制:
concat(axis=1)默认按索引标签对齐,天然就是“并集”逻辑,这也是为什么先要把公共列设为索引; - 如果原始数据里有重复的 id,需要提前去重,或者明确指定
join="outer"(默认就是 outer); - 如果想要更清晰的列结构,可以用
pd.concat(..., keys=["df1", "df2"])生成 MultiIndex 列,然后再通过result.columns = result.columns.map('_'.join)扁平化,这样列名会更规整; - 不推荐用
merge来实现这个需求——merge 本质是笛卡尔式连接,多个表合并时要多次调用,而且全外连接语义的表达远不如 concat 清晰。
这个方法简洁、高效,而且可以轻松扩展到任意多个 DataFrame。可以说,它是 Pandas 中横向构建宽表的标准实践,值得作为日常工具箱里的首选方案。
Windows 10 是一款微软推出的经典操作系统,拥有硬件兼容性与多任务处理能力。它更偏向把系统状态查看和常用调节动作放在一起,适合需要持续观察和微调设备状态的场景。
极度公式是一款跨平台专业LaTeX公式识别编辑软件,支持OCR公式识别和多平台编辑。和使用说明,避免使用,享受完整功能与稳定支持。做扫描整理、文字提取和表格转换时,它能把识别后的处理步骤接得更顺,资料录入这类场景会省下不少时间。
















