杰瑞科技汇

Python DataFrame如何高效匹配数据?

我将从最核心的 布尔索引 开始,然后介绍更强大的 query() 方法,最后讲解如何使用 merge() 函数进行类似 SQL 的表匹配。

Python DataFrame如何高效匹配数据?-图1
(图片来源网络,侵删)

准备工作:创建示例 DataFrame

为了方便演示,我们先创建两个示例 DataFrame。

import pandas as pd
import numpy as np
# 创建第一个 DataFrame:员工信息
df_employees = pd.DataFrame({
    'employee_id': [101, 102, 103, 104, 105],
    'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'department': ['HR', 'IT', 'IT', 'Finance', 'HR'],
    'salary': [70000, 85000, 90000, 75000, 68000],
    'join_date': pd.to_datetime(['2025-01-15', '2025-03-10', '2025-07-22', '2025-02-01', '2025-11-30'])
})
# 创建第二个 DataFrame:部门预算
df_budgets = pd.DataFrame({
    'department': ['HR', 'IT', 'Finance', 'Marketing'],
    'budget_2025': [500000, 1200000, 800000, 600000],
    'manager': ['Mr. Smith', 'Ms. Jones', 'Mr. Brown', 'Ms. Lee']
})
print("--- 员工信息 ---")
print(df_employees)
print("\n--- 部门预算 ---")
print(df_budgets)

输出:

--- 员工信息 ---
   employee_id     name department  salary  join_date
0          101    Alice         HR   70000 2025-01-15
1          102      Bob         IT   85000 2025-03-10
2          103  Charlie         IT   90000 2025-07-22
3          104    David    Finance   75000 2025-02-01
4          105      Eve         HR   68000 2025-11-30
--- 部门预算 ---
  department  budget_2025    manager
0         HR       500000   Mr. Smith
1         IT      1200000   Ms. Jones
2    Finance       800000  Mr. Brown
3   Marketing       600000    Ms. Lee

布尔索引 - 最核心的匹配方式

这是 Pandas 中最常用、最基础的匹配/筛选方法,其基本思想是:创建一个由 TrueFalse 组成的 Series(布尔掩码),然后用这个掩码来筛选 DataFrame 的行。

1 单条件匹配

匹配 department 为 'IT' 的所有员工。

Python DataFrame如何高效匹配数据?-图2
(图片来源网络,侵删)
# 条件:department 列等于 'IT'
condition_it = df_employees['department'] == 'IT'
# 使用方括号进行筛选
it_employees = df_employees[condition_it]
print(it_employees)

输出:

   employee_id     name department  salary  join_date
1          102      Bob         IT   85000 2025-03-10
2          103  Charlie         IT   90000 2025-07-22

核心语法:df[df['column_name'] == value]

2 多条件匹配

可以使用 & (与)、 (或)、 (非) 来组合多个条件。注意:每个条件都必须用括号 括起来!

示例:查找 IT 部门薪资高于 88000 的员工

Python DataFrame如何高效匹配数据?-图3
(图片来源网络,侵删)
# 条件1:部门是 IT
condition_dept = df_employees['department'] == 'IT'
# 条件2:薪资大于 88000
condition_salary = df_employees['salary'] > 88000
# 使用 & (AND) 组合两个条件
high_paid_it_employees = df_employees[condition_dept & condition_salary]
print(high_paid_it_employees)

输出:

   employee_id     name department  salary  join_date
2          103  Charlie         IT   90000 2025-07-22

核心语法:df[(condition1) & (condition2)]

3 使用 isin() 匹配多个值

如果你想匹配某一列是多个值中的一个,isin() 是非常方便的工具。

示例:查找 HR 和 Finance 部门的员工

# 创建一个包含目标部门的列表
target_departments = ['HR', 'Finance']
# 使用 isin() 方法
hr_finance_employees = df_employees[df_employees['department'].isin(target_departments)]
print(hr_finance_employees)

输出:

   employee_id     name department  salary  join_date
0          101    Alice         HR   70000 2025-01-15
3          104    David    Finance   75000 2025-02-01
4          105      Eve         HR   68000 2025-11-30

4 使用 str.contains() 进行字符串模糊匹配

如果你想匹配列中包含某个字符串的行,可以使用 .str.contains()

示例:查找名字中包含 'a' 的员工

# na=False 表示将 NaN 值视为 False,避免报错
employees_with_a = df_employees[df_employees['name'].str.contains('a', na=False)]
print(employees_with_a)

输出:

   employee_id     name department  salary  join_date
0          101    Alice         HR   70000 2025-01-15
2          103  Charlie         IT   90000 2025-07-22
3          104    David    Finance   75000 2025-02-01

query() 方法 - 更简洁的查询语法

query() 方法提供了一种更接近自然语言的查询方式,当条件复杂时,代码可读性更高。

1 基本用法

示例:查找 IT 部门薪资高于 88000 的员工

# 使用 query 方法
high_paid_it_employees_query = df_employees.query("department == 'IT' and salary > 88000")
print(high_paid_it_employees_query)

输出与之前完全相同。

优势:

  • 无需反复输入 df_employees['...'],可以直接使用列名。
  • 括号 仍然用于分组,但语法更直观。

2 在 query() 中引用外部变量

如果你想在外部定义一个变量并在 query() 中使用,需要在变量名前加上 符号。

示例:查找薪资高于某个特定值的员工

salary_threshold = 85000
# 使用 @ 引用外部变量
high_salary_employees = df_employees.query(f"salary > @{salary_threshold}")
print(high_salary_employees)

输出:

   employee_id     name department  salary  join_date
2          103  Charlie         IT   90000 2025-07-22

merge() 函数 - 数据库式的表匹配

当你需要将两个 DataFrame 的列根据某个共同的键(key)进行合并时,merge() 就派上用场了,这类似于 SQL 中的 JOIN 操作。

我们将使用上面创建的 df_employeesdf_budgets

1 内连接 - how='inner' (默认)

只保留两个 DataFrame 中键值匹配的行。

示例:将员工信息与部门预算合并,只显示有预算的部门员工

# 默认 how='inner'
merged_inner = pd.merge(df_employees, df_budgets, on='department')
print(merged_inner)

输出:

   employee_id     name department  salary  join_date  budget_2025    manager
0          101    Alice         HR   70000 2025-01-15      500000   Mr. Smith
1          105      Eve         HR   68000 2025-11-30      500000   Mr. Smith
2          102      Bob         IT   85000 2025-03-10     1200000   Ms. Jones
3          103  Charlie         IT   90000 2025-07-22     1200000   Ms. Jones
4          104    David    Finance   75000 2025-02-01      800000  Mr. Brown
  • Marketing 部门没有员工,所以不出现。
  • EveAlice 都在 HR 部门,所以她们的记录都与 HR 的预算信息合并了。

2 左连接 - how='left'

保留左边 DataFrame (df_employees) 的所有行,右边 DataFrame (df_budgets) 中没有匹配的键值会用 NaN 填充。

示例:查看所有员工及其部门预算(如果部门没有预算则显示 NaN)

merged_left = pd.merge(df_employees, df_budgets, on='department', how='left')
print(merged_left)

输出:

   employee_id     name department  salary  join_date  budget_2025    manager
0          101    Alice         HR   70000 2025-01-15      500000   Mr. Smith
1          102      Bob         IT   85000 2025-03-10     1200000   Ms. Jones
2          103  Charlie         IT   90000 2025-07-22     1200000   Ms. Jones
3          104    David    Finance   75000 2025-02-01      800000  Mr. Brown
4          105      Eve         HR   68000 2025-11-30      500000   Mr. Smith
  • 所有员工都保留了,因为左连接保证了 df_employees 的完整性。

3 右连接 - how='right'

保留右边 DataFrame (df_budgets) 的所有行,左边 DataFrame (df_employees) 中没有匹配的键值会用 NaN 填充。

示例:查看所有部门及其员工(如果部门没有员工则显示 NaN)

merged_right = pd.merge(df_employees, df_budgets, on='department', how='right')
print(merged_right)

输出:

   employee_id     name department  salary  join_date  budget_2025    manager
0        101.0    Alice         HR   70000 2025-01-15      500000   Mr. Smith
1        105.0      Eve         HR   68000 2025-11-30      500000   Mr. Smith
2        102.0      Bob         IT   85000 2025-03-10     1200000   Ms. Jones
3        103.0  Charlie         IT   90000 2025-07-22     1200000   Ms. Jones
4        104.0    David    Finance   75000 2025-02-01      800000  Mr. Brown
5          NaN      NaN   Marketing      NaT        NaT      600000    Ms. Lee
  • Marketing 部门被保留了,因为它在右边的 df_budgets 中,但没有员工,所以员工信息列显示为 NaN

4 外连接 - how='outer'

保留两个 DataFrame 的所有行,没有匹配的键值都用 NaN 填充。

示例:查看所有员工和所有部门的信息,无论是否能匹配上

merged_outer = pd.merge(df_employees, df_budgets, on='department', how='outer')
print(merged_outer)

输出:

   employee_id     name department  salary  join_date  budget_2025    manager
0        101.0    Alice         HR   70000 2025-01-15      500000   Mr. Smith
1        105.0      Eve         HR   68000 2025-11-30      500000   Mr. Smith
2        102.0      Bob         IT   85000 2025-03-10     1200000   Ms. Jones
3        103.0  Charlie         IT   90000 2025-07-22     1200000   Ms. Jones
4        104.0    David    Finance   75000 2025-02-01      800000  Mr. Brown
5          NaN      NaN   Marketing      NaT        NaT      600000    Ms. Lee
  • 这是左连接和右连接的并集。

总结与选择建议

场景 推荐方法 描述
根据条件筛选行 布尔索引 (df[df['A'] > 5]) 最基础、最灵活、性能最好,适用于几乎所有筛选场景。
条件复杂,追求可读性 query() 方法 (df.query("A > 5 and B == 'X'")) 语法更简洁,接近自然语言,适合复杂条件。
需要匹配多个值 isin() (df[df['A'].isin([1, 2, 3])]) 检查某列的值是否存在于给定的列表中,非常高效。
需要合并两个表 merge() 函数 (pd.merge(df1, df2, on='key')) 类似 SQL 的 JOIN 操作,用于基于键值合并多个 DataFrame 的列。

简单记忆:

  • 筛选行 -> 用 []query()
  • 合并表 -> 用 merge()

希望这份详细的指南能帮助你掌握 Pandas DataFrame 的匹配操作!

分享:
扫描分享到社交APP
上一篇
下一篇