当前位置:首页>python>【零基础玩转Python】Day41:条件筛选与查询 – query, isin, between,写出更优雅的筛选条件

【零基础玩转Python】Day41:条件筛选与查询 – query, isin, between,写出更优雅的筛选条件

  • 2026-10-11 05:47:51
【零基础玩转Python】Day41:条件筛选与查询 – query, isin, between,写出更优雅的筛选条件

【零基础玩转Python】Day41:条件筛选与查询 – query, isin, between,写出更优雅的筛选条件

大家好,我是[知识充电宝的灵感日记]。

前面我们用布尔索引(df[df['列'] > 值])已经能做很多筛选。但当条件变多、变复杂时,这种写法可能变得冗长。今天我们来学习三种更优雅的筛选方法:query()、isin()、between(),让代码更可读、更简洁。

今天的目标:

  • ✅ 使用 isin()筛选属于某个集合的行
  • ✅ 使用 between()筛选区间内的数值
  • ✅ 使用 query()写出类似 SQL 的筛选语句
  • ✅ 结合多个条件(与、或、非)
  • ✅ 实战:筛选电商订单数据

难度:⭐⭐(语法简单,但 query 需要适应字符串写法)

一、准备工作

import pandas as pd

df = pd.DataFrame({
'姓名': ['张三', '李四', '王五', '赵六', '小明', '小红'],
'年龄': [18, 20, 19, 22, 21, 19],
'成绩': [85, 92, 78, 88, 95, 82],
'城市': ['北京', '上海', '广州', '北京', '上海', '广州'],
'是否通过': [True, True, False, True, True, False]
})
print(df)
   姓名  年龄  成绩  城市   是否通过
0  张三  18  85  北京   True
1  李四  20  92  上海   True
2  王五  19  78  广州  False
3  赵六  22  88  北京   True
4  小明  21  95  上海   True
5  小红  19  82  广州  False

二、isin():筛选属于某个集合的行

isin()用于判断某列的值是否在指定的列表/集合中。

# 筛选城市为 '北京' 或 '上海' 的学生
cities = ['北京', '上海']
filtered = df[df['城市'].isin(cities)]
print(filtered)
   姓名  年龄  成绩  城市  是否通过
0  张三  18  85  北京  True
1  李四  20  92  上海  True
3  赵六  22  88  北京  True
4  小明  21  95  上海  True

取反:用 ~ 符号,筛选不在集合中的行。

# 不是北京也不是上海
filtered = df[~df['城市'].isin(cities)]
print(filtered)  # 王五、小红
   姓名  年龄  成绩  城市   是否通过
2  王五  19  78  广州  False
5  小红  19  82  广州  False

三、between():筛选区间内的数值

between(left, right, inclusive='both')用于筛选某列值在 [left, right] 区间内的行(默认包含边界)。

# 筛选成绩在 80 到 90 分之间的学生(包含边界)
filtered = df[df['成绩'].between(80, 90)]
print(filtered)
   姓名  年龄  成绩  城市   是否通过
0  张三  18  85  北京   True
3  赵六  22  88  北京   True
5  小红  19  82  广州  False

参数 inclusive='left'或 'right'可控制开闭区间。

四、query():SQL 风格的筛选

query()方法允许你使用字符串表达式进行筛选,语法简洁,尤其适合多条件组合。

基本用法

# 筛选成绩大于 80 的学生
filtered = df.query('成绩 > 80')
print(filtered)
   姓名  年龄  成绩  城市   是否通过
0  张三  18  85  北京   True
1  李四  20  92  上海   True
3  赵六  22  88  北京   True
4  小明  21  95  上海   True
5  小红  19  82  广州  False

多条件:与 (& 或 and)、或 (| 或 or)

# 成绩大于 80 且年龄小于 21
filtered = df.query('成绩 > 80 and 年龄 < 21')
# 或者用 & 符号(注意字符串内也要写 &)
filtered2 = df.query('成绩 > 80 & 年龄 < 21')

使用变量:在表达式前加 @ 引用外部变量

min_score = 85
filtered = df.query('成绩 >= @min_score')
print(filtered)
   姓名  年龄  成绩  城市  是否通过
0  张三  18  85  北京  True
1  李四  20  92  上海  True
3  赵六  22  88  北京  True
4  小明  21  95  上海  True

字符串列的条件

# 城市为北京或上海
filtered = df.query("城市 in ['北京', '上海']")
# 或使用 @ 引用列表
cities = ['北京', '上海']
filtered = df.query("城市 in @cities")

布尔列直接筛选

# 筛选通过的学生
filtered = df.query('是否通过 == True')
# 或直接写列名(因为本身就是布尔)
filtered = df.query('是否通过')

模糊匹配(使用字符串方法)

# query 中可以使用字符串方法,但需要调用
df = pd.DataFrame({'姓名': ['张三', '张飞', '李四']})
filtered = df.query('姓名.str.startswith("张")')

五、三种方法对比

方法
语法风格
适用场景
优点
布尔索引
df[df['列'] > 值]
简单单条件
直观,学习成本低
isin()
df[df['列'].isin(list)]
集合成员判断
清晰表达“属于”
between()
df[df['列'].between(a,b)]
区间范围
语法优美,包含边界可调
query()
df.query('列 > 值')
多条件、复杂逻辑
简洁、可读性强、支持变量

建议:简单条件用布尔索引;多条件或复杂字符串条件用 query()。

六、实战小案例

案例1:筛选电商订单数据

orders = pd.DataFrame({
'订单号': [101, 102, 103, 104, 105],
'金额': [150, 80, 200, 45, 300],
'状态': ['已完成', '已取消', '已完成', '已完成', '待付款'],
'用户等级': ['A', 'B', 'A', 'C', 'A']
})

# 1. 金额在 100 到 250 之间
filtered = orders.query('金额.between(100, 250)')

# 2. 状态为'已完成' 且 用户等级为'A' 或 'B'
filtered = orders.query("状态 == '已完成' and 用户等级 in ['A', 'B']")

# 3. 订单号不是 103,105
filtered = orders.query('订单号 not in [103, 105]')
print(filtered)
   订单号   金额   状态 用户等级
0  101  150  已完成    A
1  102   80  已取消    B
3  104   45  已完成    C

案例2:筛选泰坦尼克数据集的部分乘客

# 加载数据
df = pd.read_csv('https://raw.githubusercontent.com/datasciencedojo/datasets/master/titanic.csv')

# 筛选:年龄在 20~40 之间,票价大于 30,且舱位为 1 或 2 等
filtered = df.query('20 <= Age <= 40 and Fare > 30 and Pclass in [1, 2]')
print(filtered.shape)

案例3:结合 query 和变量

min_age = 18
max_age = 30
min_score = 80
filtered = df.query('@min_age <= 年龄 <= @max_age and 成绩 >= @min_score')
print(filtered)

七、今日练习

  1. 使用上面的示例 DataFrame df,完成以下筛选:

    • a) 年龄为 19 或 20 岁的学生
    • b) 成绩在 80 到 90 分之间(包含边界)的学生
    • c) 成绩大于 80 且城市不是广州的学生(用 query 实现)
  2. 用 isin() 筛选出城市为 '北京' 或 '上海' 的男生(假设有 '性别' 列,可自己添加)。

  3. 给定 df 如下:

df = pd.DataFrame({
'产品': ['A', 'B', 'C', 'D'],
'销量': [150, 80, 200, 45],
'库存': [20, 15, 0, 8]
})

用 query 筛选出:销量大于 100 且库存大于 0 的产品。

  1. (挑战)从以下 URL 加载数据集 df = pd.read_csv('https://raw.githubusercontent.com/mwaskom/seaborn-data/master/tips.csv'),用 query 筛选出:
  • 吸烟者(smoker = Yes)
  • 用餐时间(time = Dinner)
  • 总消费(total_bill)大于 20 且小于 40
  • 小费(tip)大于 5

并输出符合条件的行数。

八、常见错误与提示

  • query 中列名包含空格:需要用反引号括起来,如 df.query('列 名'] > 1")`。
  • query 中字符串必须用引号:如 "城市 == '北京'",不能省略。
  • isin 括号内是列表:注意多写一层括号,如 df['列'].isin([1,2,3])。
  • between 默认包含边界:可通过 inclusive参数调整。
  • query 性能:对于大型 DataFrame,query 通常比布尔索引略快(使用 numexpr 引擎)。
  • 取反操作:布尔索引用 ~,query中用 not或 !=。

九、明日预告

Day42:数据排序与排名 – sort_values, rank

我们将学习如何对 DataFrame 按单列或多列排序,以及如何计算排名。

最新文章

随机文章