当前位置:首页>python>Python数据分析:搞懂 pandas 中的 concat、merge、join:三者到底有什么区别?

Python数据分析:搞懂 pandas 中的 concat、merge、join:三者到底有什么区别?

  • 2026-09-02 20:15:21
Python数据分析:搞懂 pandas 中的 concat、merge、join:三者到底有什么区别?

🔗 搞懂 pandas 中的 concat、merge、join:三者到底有什么区别?

你是不是也经常困惑:

  • 什么时候用 pd.concat()?
  • 什么时候该用 df.merge()?
  • df.join() 又是什么?跟 merge 有啥不同?

别急!今天我们就用最直白的语言 + 可运行的代码,一次性讲清楚这三个“拼表”操作的区别和使用场景!

❝

✅ 所有示例数据均由代码生成,无需任何外部文件,复制即用!


🧰 准备工作:导入库 + 构造示例数据

import pandas as pd# 表1:用户基本信息users = pd.DataFrame({'user_id': [1, 2, 3, 4],'name': ['Alice', 'Bob', 'Charlie', 'Diana'],'city': ['北京', '上海', '广州', '深圳']})# 表2:用户订单信息orders = pd.DataFrame({'order_id': [101, 102, 103, 104],'user_id': [1, 2, 3, 5],  # 注意:user_id=5 在 users 中不存在'amount': [200, 150, 300, 99]})# 表3:用户登录日志(索引为 user_id)logins = pd.DataFrame({'last_login': ['2026-02-10', '2026-02-12', '2026-02-13', '2026-02-14']}, index=[1, 2, 3, 4])  # 索引是 user_id

现在我们有三张表:

  • users:用户主表(含 user_id)
  • orders:订单表(通过 user_id 关联)
  • logins:登录日志(以 user_id 为索引)

接下来,就看它们如何“拼”在一起!


1️⃣ pd.concat():上下 or 左右“堆叠”——结构相同,直接拼接

❝

🎯 适用场景:合并多个结构相似的 DataFrame(比如多个月份的销售表、多个实验结果)

示例:纵向拼接(axis=0,默认)

extra_users = pd.DataFrame({'user_id': [5, 6],'name': ['Eva', 'Frank'],'city': ['杭州', '成都']})all_users = pd.concat([users, extra_users], ignore_index=True)print(all_users)

✅ 输出:6 行用户数据,“堆”在一起。

示例:横向拼接(axis=1)

# 把 users 和 logins 按索引横向拼(需对齐索引)result = pd.concat([users.set_index('user_id'), logins], axis=1)print(result)

⚠️ 注意:concat不基于列内容匹配,只按索引或位置对齐!

❝

✅ 核心特点:

  • 像“粘贴”一样堆叠数据
  • 不涉及“关联字段”匹配
  • 适合同构数据合并

2️⃣ df.merge():基于列值的“数据库式连接”——最常用!

❝

🎯 适用场景:两张表通过某个公共字段(如 ID)关联,类似 SQL 的 JOIN

示例:内连接(inner join)

merged = users.merge(orders, on='user_id', how='inner')print(merged)

✅ 输出:只保留 user_id 在两张表中都存在的记录(user_id=1,2,3)

支持多种连接方式:

  • how='left':保留左表全部(users 全部,orders 缺失补 NaN)
  • how='right':保留右表全部
  • how='outer':全保留,缺失补 NaN

还支持不同名列的连接:

# 如果 users 用 'id',orders 用 'user_id'users2 = users.rename(columns={'user_id': 'id'})result = users2.merge(orders, left_on='id', right_on='user_id')
❝

✅ 核心特点:

  • 基于列的值进行匹配
  • 功能最强大、最灵活
  • 日常分析 80% 场景用它!

3️⃣ df.join():基于索引的快速连接

❝

🎯 适用场景:一张表的索引 = 另一张表的索引(或某列)

示例:用 users 的 user_id 作为索引,去 join logins

users_indexed = users.set_index('user_id')joined = users_indexed.join(logins)  # 默认 left joinprint(joined)

✅ 输出:users 的每一行,自动匹配 logins 中对应索引的登录时间。

也可以指定右表用哪一列做索引:

# 如果 logins 不是以 user_id 为索引,而是普通列logins2 = pd.DataFrame({'user_id': [1, 2, 3, 4],'last_login': ['2026-02-10', '2026-02-12', '2026-02-13', '2026-02-14']})# 需先设索引joined2 = users_indexed.join(logins2.set_index('user_id'))
❝

✅ 核心特点:

  • 默认按索引对齐
  • 本质是 merge 的快捷方式(join 底层调用 merge)
  • 适合“主表索引 + 附属信息表”的场景

🆚 三者对比速查表

方法
对齐依据
类似 SQL
典型用途
是否需要公共列
pd.concat()
索引 / 位置
UNION ALL
合并多份同结构数据
❌ 不需要
df.merge()
列的值
JOIN
通过 ID/键关联两张表
✅ 需要
df.join()
索引(或指定列)
JOIN
主表(索引为ID)+ 附属信息表
⚠️ 通常需设索引

💡 使用建议

  • 想把多个月的报表合并成一年? → 用 concat
  • 想把用户表和订单表关联起来? → 用 merge
  • 你的主表已经用 ID 设为索引,想快速加一列信息? → 用 join
❝

🌟 记住一句话:“concat 是堆叠,merge 是匹配,join 是索引对齐。”


📦 结语

掌握 concat、merge、join 的区别,是迈向高效数据处理的关键一步!下次再遇到“怎么把两张表合起来”的问题,先问自己:👉 我是要堆数据?还是按字段匹配?还是按索引补充信息?


❤️ 觉得有用?点赞 + 在看 + 转发,让更多人告别“拼表混乱”!


最新文章

随机文章