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

Pandas df.query() 函数

Pandas 常用函数 Pandas 常用函数


query() 是 Pandas 中非常实用的数据筛选函数,它允许使用类似 SQL 的字符串表达式来筛选数据。相比于传统的布尔索引方式,query() 的语法更加简洁直观,特别适合处理复杂的筛选条件。

在数据分析工作中,经常需要根据各种条件筛选数据。query() 函数将筛选条件写成字符串形式,就像写 SQL 查询一样,这对于熟悉 SQL 的用户来说非常友好。同时,它也支持使用 Python 变量和函数,使动态筛选成为可能。


基本语法与参数

query() 是 DataFrame 的方法,通过点运算符 . 来调用。它接受一个字符串参数,该字符串包含筛选表达式。

语法格式

DataFrame.query(expr, inplace=False, **kwargs)

参数说明

参数 类型 是否必填 说明 默认值
expr str 必填 筛选表达式,类似于 SQL 的 WHERE 子句。 -
inplace bool 可选 是否在原 DataFrame 上直接修改。 False

返回值说明

  • 返回值类型: 返回一个新的 DataFrame,包含满足筛选条件的行。
  • 不修改原数据: 默认情况下,原 DataFrame 保持不变。

实例

让我们通过丰富的例子全面掌握 query() 的用法。

示例 1:基础用法 - 单条件筛选

最简单的 query() 用法是使用单个条件进行筛选。

实例

import pandas as pd

# 创建示例 DataFrame
data = {
    'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank', 'Grace'],
    'age': [18, 19, 17, 18, 20, 19, 18],
    'score': [85, 92, 78, 90, 88, 95, 82],
    'grade': ['A', 'A', 'B', 'A', 'B', 'A', 'B']
}
df = pd.DataFrame(data)

print("原始 DataFrame:")
print(df)
print()

# 筛选分数大于 85 的学生
print("分数大于 85 的学生:")
print(df.query('score > 85'))
print()

# 筛选年龄等于 18 的学生
print("年龄等于 18 的学生:")
print(df.query('age == 18'))
print()

# 筛选等级为 A 的学生
print("等级为 A 的学生:")
print(df.query('grade == "A"'))

运行结果:

原始 DataFrame:
      name  age  score grade
0    Alice   18     85     A
1      Bob   19     92     A
2  Charlie   17     78     B
3    David   18     90     A
4      Eve   20     88     B
5    Frank   19     95     A
6    Grace   18     82     B

分数大于 85 的学生:
      name  age  score grade
1      Bob   19     92     A
3    David   18     90     A
4      Eve   20     88     B
5    Frank   19     95     A

年龄等于 18 的学生:
      name  age  score grade
0    Alice   18     85     A
3    David   18     90     A
6    Grace   18     82     B

等级为 A 的学生:
      name  age  score grade
0    Alice   18     85     A
1      Bob   19     92     A
3    David   18     90     A
5    Frank   19     95     A

代码解析:

  1. 筛选条件放在引号中,使用类似 SQL 的语法。
  2. 数值比较使用 >, ==, < 等运算符。
  3. 字符串比较使用双引号或单引号。

示例 2:复合条件筛选

query() 支持使用逻辑运算符组合多个条件。

实例

import pandas as pd

data = {
    'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank', 'Grace'],
    'age': [18, 19, 17, 18, 20, 19, 18],
    'score': [85, 92, 78, 90, 88, 95, 82],
    'grade': ['A', 'A', 'B', 'A', 'B', 'A', 'B']
}
df = pd.DataFrame(data)

# 使用 AND 条件:分数大于 85 且年龄小于 19
print("分数大于 85 且年龄小于 19 的学生:")
print(df.query('score &gt; 85 and age  90'))
print()

# 使用 NOT 条件:等级不为 A
print("等级不为 A 的学生:")
print(df.query('not grade == "A"'))
print()

# 复杂的复合条件
print("年龄在 18 到 20 之间且分数不等于 88 的学生:")
print(df.query('age &gt;= 18 and age &lt;= 20 and score != 88&#039;))

运行结果:

分数大于 85 且年龄小于 19 的学生:
      name  age  score grade
3    David   18     90     A
5    Frank   19     95     A

等级为 A 或分数大于 90 的学生:
      name  age  score grade
1      Bob   19     92     A
3    David   18     90     A
5    Frank   19     95     A

等级不为 A 的学生:
      name  age  score grade
2  Charlie   17     78     B
4      Eve   20     88     B
6    Grace   18     82     B

年龄在 18 到 20 之间且分数不等于 88 的学生:
      name  age  score grade
0    Alice   18     85     A
1      Bob   19     92     A
3    David   18     90     A
5    Frank   19     95     A

代码解析:

  1. 使用 and 表示逻辑与运算。
  2. 使用 or 表示逻辑或运算。
  3. 使用 not 表示逻辑非运算。
  4. 复合条件可以任意组合,形成复杂的筛选逻辑。

示例 3:使用 Python 变量

query() 支持在表达式中使用 Python 变量,这在动态查询中非常有用。

实例

import pandas as pd

data = {
    'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank', 'Grace'],
    'age': [18, 19, 17, 18, 20, 19, 18],
    'score': [85, 92, 78, 90, 88, 95, 82],
    'grade': ['A', 'A', 'B', 'A', 'B', 'A', 'B']
}
df = pd.DataFrame(data)

# 使用 @ 符号引用 Python 变量
min_score = 85
target_grade = 'A'

print("使用变量筛选 - 分数大于 {}:".format(min_score))
print(df.query('score &gt; @min_score'))
print()

print("使用变量筛选 - 等级为 '{}':".format(target_grade))
print(df.query('grade == @target_grade'))
print()

# 使用列表作为变量
target_grades = ['A', 'B']
print("等级在 {} 中的学生:".format(target_grades))
print(df.query('grade in @target_grades'))
print()

# 使用 Python 函数
def get_average_score(df):
    return df['score'].mean()

print("分数高于平均分的学生:")
print(df.query('score &gt; @get_average_score(df)'))

运行结果:

使用变量筛选 - 分数大于 85:
      name  age  score grade
1      Bob   19     92     A
3    David   18     90     A
4      Eve   20     88     B
5    Frank   19     95     A

使用变量筛选 - 等级为 'A':
      name  age  score grade
0    Alice   18     85     A
1      Bob   19     92     A
3    David   18     90     A
5    Frank   19     95     A

等级在 ['A', 'B'] 中的学生:
      name  age  score grade
0    Alice   18     85     A
1      Bob   19     92     A
2  Charlie   17     78     B
3    David   18     90     A
4      Eve   20     88     B
5    Frank   19     95     A
6    Grace   18     82     B

分数高于平均分的学生:
      name  age  score grade
1      Bob   19     92     A
3    David   18     90     A
5    Frank   19     95     A

代码解析:

  • 使用 @ 符号可以在查询表达式中引用 Python 变量。
  • 可以直接使用 Python 列表进行 in 判断。
  • 可以调用 Python 函数来计算动态阈值。

示例 4:字符串操作

query() 还支持一些常见的字符串操作。

实例

import pandas as pd

# 创建带有字符串列的 DataFrame
data = {
    'name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve', 'Frank', 'Grace'],
    'city': ['Beijing', 'Shanghai', 'Beijing', 'Guangzhou', 'Shanghai', 'Beijing', 'Shenzhen'],
    'score': [85, 92, 78, 90, 88, 95, 82]
}
df = pd.DataFrame(data)

# 筛选特定城市的记录
print("在北京的学生:")
print(df.query('city == "Beijing"'))
print()

# 字符串包含判断(使用 in)
print("在上海或北京的学生:")
print(df.query('city in ["Shanghai", "Beijing"]'))
print()

# 使用 @ 引用包含字符串的变量
target_city = 'Guangzhou'
print("在 {} 的学生:".format(target_city))
print(df.query('city == @target_city'))

运行结果:

在北京的学生:
      name      city  score
0    Alice   Beijing     85
2  Charlie   Beijing     78
5    Frank   Beijing     95

在上海或北京的学生:
      name      city  score
0    Alice   Beijing     85
1      Bob   Shanghai     92
2  Charlie   Beijing     78
4      Eve   Shanghai     88
5    Frank   Beijing     95

在 Guangzhou 的学生:
      name       city  score
3    David  Guangzhou     90

代码解析:

  • query() 支持字符串的相等比较。
  • 可以使用 in 关键字判断元素是否在列表中。
  • 可以使用 @ 引用字符串变量。

示例 5:处理列名中有空格或特殊字符的情况

如果列名包含空格或特殊字符,可以使用反引号 `` ` `` 包裹列名。

实例

import pandas as pd

# 创建列名包含空格的 DataFrame
data = {
    'student name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'score': [85, 92, 78, 90, 88],
    'pass status': [True, True, False, True, True]
}
df = pd.DataFrame(data)

print("原始 DataFrame(列名包含空格):")
print(df)
print()

# 使用反引号包裹列名
print("分数大于 85 的学生:")
print(df.query('`score` &gt; 85'))
print()

print("通过状态为 True 的学生:")
print(df.query('`pass status` == True'))
print()

# 也可以用这个方法处理保留字作为列名
df2 = pd.DataFrame({
    'class': ['A', 'B', 'A', 'B', 'A'],
    'def': [1, 2, 3, 4, 5]  # def 是 Python 保留字
})
print("使用保留字作为列名:")
print(df2.query('`def` &gt; 3'))

运行结果:

原始 DataFrame(列名包含空格):
  student name  score  pass status
0       Alice     85        True
1         Bob     92        True
2    Charlie     78       False
3     David   90        True
4        Eve     88        True

分数大于 85 的学生:
  student name  score  pass status
1         Bob     92        True
3       David     90        True
4        Eve     88        True

通过状态为 True 的学生:
  student name  score  pass status
0       Alice     85        True
1         Bob     92        True
3       David     90        True
4        Eve     88        True

使用保留字作为列名:
  class  def
3     B    4
4     A    5

代码解析:

  • 通过使用反引号,可以处理列名包含空格或与 Python 保留字冲突的情况。
  • `score``pass status` 用于引用列名。
  • `def` 展示了如何处理 Python 保留字作为列名。

注意事项

  • query() 表达式中的列名必须是有效的 Python 标识符,或者用反引号包裹。
  • 字符串比较可以使用单引号或双引号。
  • 使用 @ 符号引用 Python 变量。
  • 对于大型 DataFrame,query() 的性能通常优于传统的布尔索引。
  • 如果筛选表达式中有保留字或特殊字符,必须使用反引号。

提示:query() 特别适合需要动态构建筛选条件的场景,比如根据用户输入或配置文件来筛选数据。结合 Python 的字符串格式化功能,可以实现非常灵活的数据查询。


小结

query() 是 Pandas 中强大的数据筛选函数,它提供了类似 SQL 的查询语法,使复杂的条件筛选变得更加简洁和易读。

它的主要优势包括:语法简洁直观、支持复合逻辑运算、支持 Python 变量和函数、可以处理特殊列名。在实际数据分析中,特别是需要动态构建筛选条件时,query() 是一个非常实用的工具。

Pandas 常用函数 Pandas 常用函数