Pandas pd.merge() 函数
pd.merge() 是 Pandas 库中用于按列连接两个 DataFrame的函数。它类似于 SQL 中的 JOIN 操作,可以基于一个或多个公共列将两个数据表合并成一个。
这是数据分析和处理中最常用的合并方式之一,特别适合处理关系型数据,将分散在不同表中的相关信息整合到一起。
单词释义: merge 意为"合并、融合",在这里指将两个数据表根据共同的键合并在一起。
基本语法与参数
pd.merge() 是 Pandas 库的顶级函数,用于实现类似于 SQL 中的 JOIN 操作。
语法格式
pd.merge(left, right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)
参数说明
- 参数:
left- 类型: DataFrame。
- 描述: 左侧的 DataFrame,参与合并的第一个表。
- 参数:
right- 类型: DataFrame。
- 描述: 右侧的 DataFrame,参与合并的第二个表。
- 参数:
on- 类型: 字符串或字符串列表。
- 描述: 用于连接的列名(键)。左右两个 DataFrame 中必须有同名的列。如果不指定,会自动寻找同名列作为键。
- 参数:
how- 类型: 字符串('left', 'right', 'outer', 'inner')。
- 描述: 合并方式,类似于 SQL 的 JOIN 类型。
'inner'表示内连接(交集),'outer'表示外连接(并集),'left'表示左连接(保留左表全部记录),'right'表示右连接(保留右表全部记录)。默认为'inner'。
- 参数:
left_on- 类型: 字符串或字符串列表。
- 描述: 左侧 DataFrame 中用作连接键的列名。当左右两表的连接键列名不同时使用。
- 参数:
right_on- 类型: 字符串或字符串列表。
- 描述: 右侧 DataFrame 中用作连接键的列名。当左右两表的连接键列名不同时使用。
- 参数:
suffixes- 类型> 元组。
- 描述> 当左右两表有同名列(不是连接键)时,用于区分的后缀。默认为
('_x', '_y')。
函数说明
- 返回值: 返回合并后的 DataFrame。
- 效果: 根据指定的键和方法,将两个 DataFrame 横向合并为一个 DataFrame。
实例
让我们通过一系列从简单到复杂的例子,彻底掌握 pd.merge() 的用法。
示例 1:基础用法 - 基于单列的内连接
实例
import pandas as pd
# 1. 创建两个 DataFrame
employees = pd.DataFrame({
'emp_id': [101, 102, 103, 104],
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'dept_id': [1, 2, 1, 2]
})
departments = pd.DataFrame({
'dept_id': [1, 2, 3],
'dept_name': ['Engineering', 'Sales', 'Marketing']
})
print("=== 员工表 (employees) ===")
print(employees)
print("\n=== 部门表 (departments) ===")
print(departments)
# 2. 使用 pd.merge() 基于 dept_id 列合并(内连接,默认)
result = pd.merge(employees, departments, on='dept_id')
print("\n=== pd.merge(employees, departments, on='dept_id') 内连接 ===")
print(result)
# 1. 创建两个 DataFrame
employees = pd.DataFrame({
'emp_id': [101, 102, 103, 104],
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'dept_id': [1, 2, 1, 2]
})
departments = pd.DataFrame({
'dept_id': [1, 2, 3],
'dept_name': ['Engineering', 'Sales', 'Marketing']
})
print("=== 员工表 (employees) ===")
print(employees)
print("\n=== 部门表 (departments) ===")
print(departments)
# 2. 使用 pd.merge() 基于 dept_id 列合并(内连接,默认)
result = pd.merge(employees, departments, on='dept_id')
print("\n=== pd.merge(employees, departments, on='dept_id') 内连接 ===")
print(result)
运行结果预期:
=== 员工表 (employees) === emp_id name dept_id 0 101 Alice 1 1 102 Bob 2 2 103 Charlie 1 3 104 Diana 2 === 部门表 (departments) === dept_id dept_name 0 1 Engineering 1 2 Sales 2 3 Marketing === pd.merge(employees, departments, on='dept_id') 内连接 === emp_id name dept_id dept_name 0 101 Alice 1 Engineering 1 103 Charlie 1 Engineering 2 102 Bob 2 Sales 3 104 Diana 2 Sales
代码解析:
- 两个表通过
dept_id列进行连接,这是它们的公共列。 - 默认使用内连接(
how='inner'),只保留两边都有的键值(dept_id 为 1 和 2),因此 dept_id 为 3 的市场部被排除在外。 - 合并后,每个员工都关联到了对应的部门名称。
示例 2:左连接和右连接
使用 how 参数可以控制合并方式,保留其中一方的全部记录。
实例
import pandas as pd
# 继续使用上面的数据
employees = pd.DataFrame({
'emp_id': [101, 102, 103, 104],
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'dept_id': [1, 2, 1, 2]
})
departments = pd.DataFrame({
'dept_id': [1, 2, 3],
'dept_name': ['Engineering', 'Sales', 'Marketing']
})
# 1. 左连接 - 保留左表所有记录
print("=== 左连接 (how='left') ===")
left_result = pd.merge(employees, departments, on='dept_id', how='left')
print(left_result)
# 2. 右连接 - 保留右表所有记录
print("\n=== 右连接 (how='right') ===")
right_result = pd.merge(employees, departments, on='dept_id', how='right')
print(right_result)
# 3. 外连接 - 保留两表所有记录
print("\n=== 外连接 (how='outer') ===")
outer_result = pd.merge(employees, departments, on='dept_id', how='outer')
print(outer_result)
# 继续使用上面的数据
employees = pd.DataFrame({
'emp_id': [101, 102, 103, 104],
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'dept_id': [1, 2, 1, 2]
})
departments = pd.DataFrame({
'dept_id': [1, 2, 3],
'dept_name': ['Engineering', 'Sales', 'Marketing']
})
# 1. 左连接 - 保留左表所有记录
print("=== 左连接 (how='left') ===")
left_result = pd.merge(employees, departments, on='dept_id', how='left')
print(left_result)
# 2. 右连接 - 保留右表所有记录
print("\n=== 右连接 (how='right') ===")
right_result = pd.merge(employees, departments, on='dept_id', how='right')
print(right_result)
# 3. 外连接 - 保留两表所有记录
print("\n=== 外连接 (how='outer') ===")
outer_result = pd.merge(employees, departments, on='dept_id', how='outer')
print(outer_result)
运行结果预期:
=== 左连接 (how='left') === emp_id name dept_id dept_name 0 101 Alice 1 Engineering 1 103 Charlie 1 Engineering 2 102 Bob 2 Sales 3 104 Diana 2 Sales === 右连接 (how='right') === emp_id name dept_id dept_name 0 101 Alice 1 Engineering 1 103 Charlie 1 Engineering 2 102 Bob 2 Sales 3 104 Diana 2 Sales 4 NaN NaN 3 Marketing === 外连接 (how='outer') === emp_id name dept_id dept_name 0 101 Alice 1 Engineering 1 103 Charlie 1 Engineering 2 102 Bob 2 Sales 3 104 Diana 2 Sales 4 NaN NaN 3 Marketing
代码解析:
- 左连接保留左表(employees)的所有员工记录,右表没有匹配的部门显示为
NaN。 - 右连接保留右表(departments)的所有部门,即使没有员工属于该部门。
- 外连接保留两表的所有记录,没有匹配的字段用
NaN填充。
示例 3:处理列名不同的两个表
当两个表的连接键列名不同时,可以使用 left_on 和 right_on 参数分别指定。
实例
import pandas as pd
# 1. 创建列名不同的两个 DataFrame
students = pd.DataFrame({
'student_id': [1, 2, 3, 4],
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'class_id': [101, 102, 101, 103]
})
classes = pd.DataFrame({
'class_id': [101, 102, 103],
'class_name': ['Class A', 'Class B', 'Class C'],
'teacher': ['Mr. Smith', 'Ms. Johnson', 'Mrs. Lee']
})
print("=== 学生表 ===")
print(students)
print("\n=== 班级表 ===")
print(classes)
# 2. 使用 left_on 和 right_on 处理不同的列名
result = pd.merge(students, classes, left_on='class_id', right_on='class_id')
print("\n=== 不同列名时的合并 ===")
print(result)
# 1. 创建列名不同的两个 DataFrame
students = pd.DataFrame({
'student_id': [1, 2, 3, 4],
'name': ['Alice', 'Bob', 'Charlie', 'Diana'],
'class_id': [101, 102, 101, 103]
})
classes = pd.DataFrame({
'class_id': [101, 102, 103],
'class_name': ['Class A', 'Class B', 'Class C'],
'teacher': ['Mr. Smith', 'Ms. Johnson', 'Mrs. Lee']
})
print("=== 学生表 ===")
print(students)
print("\n=== 班级表 ===")
print(classes)
# 2. 使用 left_on 和 right_on 处理不同的列名
result = pd.merge(students, classes, left_on='class_id', right_on='class_id')
print("\n=== 不同列名时的合并 ===")
print(result)
运行结果预期:
=== 学生表 ===
student_id name class_id
0 1 Alice 101
1 2 Bob 102
2 3 Charlie 101
3 4 Diana 103
=== 班级表 ===
class_id class_name teacher
0 101 Class A Mr. Smith
1 102 Class B Ms. Johnson
2 103 Class C Mrs. Lee
=== 不同列名时的合并 ===
student_id name class_id class_name teacher
0 1 Alice 101 Class A Mr. Smith
1 3 Charlie 101 Class A Mr. Smith
2 2 Bob 102 Class B Indicator False
3 indicator column
print("\n=== indicator=True 显示合并详情 ===")
print(result_indicator)
[/mycode4]</div>
</div>
<p><strong>运行结果预期:</strong></p>
<pre>
=== 索引作为连接键 ===
name city score subject grade
0 Alice Beijing 85 Math A
1 Bob Shanghai 90 Math B
2 Charlie Guangzhou 95 English A
3 Diana Shenzhen 88 English B
=== 多个键的合并 ===
student_id name course_id course_name score
0 1 Alice 101 Math 90
1 1 Alice 102 English 85
2 2 Bob 101 Math 88
3 2 Bob 103 Science 92
4 3 Charlie 102 English 95
=== indicator=True 显示合并详情 ===
name city merge_info
0 Alice Beijing both
1 Bob Shanghai both
2 Charlie Guangzhou left_only
3 Diana Shenzhen left_only
代码解析:
- 使用
left_index=True和right_index=True可以使用 DataFrame 的索引作为连接键。 - 传递一个列表给
on参数可以实现多键合并,需要所有键都匹配才保留记录。 - 设置
indicator=True可以添加一个特殊列,显示每条记录来自哪个表(left_only, right_only, both)。
提示:
pd.merge()适用于基于列的合并操作。如果只需要简单地将数据纵向追加(增加行),请使用pd.concat()函数。

Pandas 常用函数