Pandas小技巧:使用query()优雅的查询

本文介绍了Pandas DataFrame中使用query方法进行数据筛选的方法,包括根据单条件、多条件筛选,引用外部变量,以及处理多索引数据。query方法使得代码更加简洁易读,并且内存效率高。示例展示了如何选取A列字母在B列中的行,以及结合其他条件如C列小于D列进行筛选。同时,文章还提到了如何处理列名包含特殊字符的情况。

对于 Pandas 根据条件获取指定数据,相信大家都能够轻松的写出相应代码,但是如果你还没用过 query,相信你会被它的简洁所折服!

常规用法

先创建一个 DataFrame。

import pandas as pd

df = pd.DataFrame(
    {'A': ['e', 'd', 'c', 'b', 'a'],
     'B': ['f', 'b', 'c', 'd', 'e'],
     'C': range(0, 10, 2),
     'D': range(10, 0, -2),
     'E.E': range(10, 5, -1)})

我们现在选取 A列字母出现在B列 的所有行。先看两种常见写法。

>>> df[df['A'].isin(df['B'])]
   A  B  C   D  E.E
0  e  f  0  10   10
1  d  b  2   8    9
2  c  c  4   6    8
3  b  d  6   4    7
>>> df.loc[df['A'].isin(df['B'])]
   A  B  C   D  E.E
0  e  f  0  10   10
1  d  b  2   8    9
2  c  c  4   6    8
3  b  d  6   4    7

下面使用 query() 来实现。

>>> df.query("A in B")
   A  B  C   D  E.E
0  e  f  0  10   10
1  d  b  2   8    9
2  c  c  4   6    8
3  b  d  6   4    7

可以看到使用 query 后的代码简洁易懂,并且它对于内存的消耗也更小。

多条件查询

选取 A列字母出现在B列,并且C列小于D列 的所有行。

>>> df.query('A in B and C < D')
   A  B  C   D  E.E
0  e  f  0  10   10
1  d  b  2   8    9
2  c  c  4   6    8

这里 and 也可以用 & 表示。

引用变量

表达式中也可以使用外部定义的变量,在变量名前用@标明。

>>> number = 5
>>> df.query('A in B & C > @number')
   A  B  C  D  E.E
3  b  d  6  4    7

索引选取

选取 A列字母出现在B列,并且索引大于2 的所有行。

>>> df.query('A in B and index > 2')
   A  B  C  D  E.E
3  b  d  6  4    7

多索引选取

创建一个两层索引的 DataFrame。

>>> import numpy as np
>>> colors = ['yellow']*3 + ['red']*2
>>> rank = [str(i) for i in range(5)]
>>> index = pd.MultiIndex.from_arrays([colors, rank], names=['color', 'rank'])
>>> df = pd.DataFrame(np.arange(10).reshape(5, 2),columns=['A', 'B'] , index=index)
>>> df = pd.DataFrame(np.arange(10).reshape(5, 2),columns=['A', 'B'] , index=index)
>>> df
             A  B
color  rank      
yellow 0     0  1
       1     2  3
       2     4  5
red    3     6  7
       4     8  9

1.当有多层索引有名称时,通过索引名称直接选取。

>>> df.query("color == 'red'")
            A  B
color rank      
red   3     6  7
      4     8  9

2.当有多层索引无名时,通过索引级别来选取。

>>> df.index.names = [None, None]
>>> df.query("ilevel_0 == 'red'")
       A  B
red 3  6  7
    4  8  9
>>> df.query("ilevel_1 == '4'")
       A  B
red 4  8  9

特殊字符

对于列名中间有空格或运算符等其他特殊符号,需要使用反引号 ``

>>> df.query('A == B | (C + 2 > `E.E`)')
   A  B  C  D  E.E
2  c  c  4  6    8
3  b  d  6  4    7
4  a  e  8  2    6

总的来说,query() 用法比较简单,可以快速上手,代码可读性也提高了不少。

<think>好的,我现在要帮助用户解决关于Pandasquery方法的使用问题。用户之前已经询问过where方法,现在转向query方法,可能需要比较两者的不同。用户还提到了站内引用,其中引用1提到query与其他方法结合使用,比如groupby和agg,这可能是一个重点。 首先,我需要回顾query的基本用法,确保涵盖语法和参数。用户可能需要知道如何编写查询字符串,特别是如何处理带有空格的列名,或者使用变量。引用1中的例子用了单引号,内部用双引号,这点要注意。 然后,考虑示例代码。用户之前给的where示例比较详细,所以这里也需要提供类似的例子,比如创建DataFrame,演示不同查询条件。可能需要包括数值比较、字符串操作、多条件组合,比如&和|,以及使用@符号引用外部变量。 接下来,高级用法部分。用户可能对性能优化感兴趣,尤其是处理大数据集时。引用1提到了query和groupby的结合,这部分要详细说明,比如筛选后做聚合操作。此外,处理特殊字符列名、使用表达式函数(如字符串方法)也是重点。 注意事项部分需要强调query的优点,比如可读性和链式操作,同时提到潜在问题,比如列名中的空格需要用反引号,或者性能问题。引用3提到DataFrame的结构,可能需要说明query如何操作整个DataFrame。 用户之前的回答中提到了where和mask的区别,所以可能也需要对比query和where的不同,但用户这次的问题集中在query,所以可能在相关问题里提到。此外,用户可能想知道何时使用query而不是where,或者如何选择。 还要检查是否有遗漏的常见问题,比如如何处理动态生成的查询条件,或者如何避免SQL注入式的安全问题。不过pandasquery方法在这方面相对安全,但可能需要提一下。 最后,生成相关问题,确保覆盖用户可能的后续疑问,比如性能优化、多表查询、条件动态构建等。同时参考之前的回答结构,保持一致性。</think>### Pandas query方法使用详解 #### 一、基本语法与核心特性 `query()`方法允许使用类SQL语法进行数据筛选,语法结构为: $$DataFrame.query(expr, inplace=False, **kwargs)$$ 核心优势: - 支持自然语言表达式(类似SQL WHERE子句) - 可直接引用外部变量(使用@符号) - 与pandas方法链完美配合[^1] #### 二、基础查询模式 ```python import pandas as pd df = pd.DataFrame({ '姓名': ['张三', '李四', '王五'], '年龄': [25, 32, 28], '薪资': [8000, 12000, 9500], '部门': ['销售部', '技术部', '财务部'] }) # 单条件查询 df.query('薪资 > 9000') # 筛选薪资高于9000的记录 # 多条件组合 df.query('(年龄 > 25) & (部门 == "技术部")') # AND条件 df.query('(薪资 < 8500) | (部门.str.contains("财务"))') # OR条件[^3] ``` #### 三、高级查询技巧 1. **变量注入查询**: ```python threshold = 30 target_dept = '技术部' df.query('年龄 < @threshold & 部门 == @target_dept') ``` 2. **字符串操作**: ```python # 模糊查询部门名称 df.query('部门.str.contains("技术")') # 包含特定字符 df.query('姓名.str.startswith("张")') # 前缀匹配 ``` 3. **复杂表达式**: ```python # 计算字段查询 df.query('薪资 / 年龄 > 300') # 薪资年龄比条件 ``` 4. **索引查询**: ```python # 使用index进行条件筛选 df.reset_index().query('index % 2 == 0') # 选择偶数行 ``` #### 四、方法链式操作 ```python # 与groupby/agg组合使用[^1] (df.query('薪资 > 5000') .groupby('部门') .agg(平均薪资=('薪资', 'mean'), 最大年龄=('年龄', 'max')) ) ``` #### 五、特殊场景处理 1. **空列名处理**: ```python # 带空格的列名使用反引号包裹 df.query('`部门名称` == "技术研发部"') ``` 2. **性能优化**: ```python # 对大型数据集启用numexpr引擎 df.query('薪资 > 5000', engine='numexpr') ``` #### 六、与where方法对比 | 特性 | query | where | |-------------|---------------------------|----------------| | 筛选逻辑 | 过滤行 | 元素级替换 | | 语法类型 | 声明式(类SQL) | 命令式 | | 性能表现 | 大数据集更优 | 小数据集更快 | | 条件表达式 | 支持复杂逻辑组合 | 仅布尔数组 | | 返回值 | 筛选后的子集 | 同结构DataFrame| #### 七、最佳实践建议 1. 优先使用`''`包裹整个表达式,内部字符串使用`""` 2. 多表查询使用`pd.eval()`扩展功能 3. 避免在循环中重复调用query方法 4. 对频繁使用查询条件建立预编译模板 --相关问题-- 1. 如何动态构建query方法的查询条件表达式? 2. query方法在连接多表查询时有哪些限制? 3. pandas.query与SQL WHERE子句有哪些语法差异? 4. 如何优化query方法在千万级数据集的查询性能?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值