现在位置: 首页 > Pandas 教程 > 正文

Pandas pd.merge() 函数

Pandas 通用函数 Pandas 常用函数


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)

运行结果预期:

=== 员工表 (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

代码解析:

  1. 两个表通过 dept_id 列进行连接,这是它们的公共列。
  2. 默认使用内连接(how='inner'),只保留两边都有的键值(dept_id 为 1 和 2),因此 dept_id 为 3 的市场部被排除在外。
  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)

运行结果预期:

=== 左连接 (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_onright_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)

运行结果预期:

=== 学生表 ===
   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=Trueright_index=True 可以使用 DataFrame 的索引作为连接键。
  • 传递一个列表给 on 参数可以实现多键合并,需要所有键都匹配才保留记录。
  • 设置 indicator=True 可以添加一个特殊列,显示每条记录来自哪个表(left_only, right_only, both)。

提示: pd.merge() 适用于基于列的合并操作。如果只需要简单地将数据纵向追加(增加行),请使用 pd.concat() 函数。

Pandas 常用函数 Pandas 常用函数