pin_drop当前位置:知识文库 ❯ 图文

pandas DataFrame筛选过滤 - 条件表达式筛选数据

一、筛选过滤概述

数据筛选是数据分析中最常用的操作之一。pandas 提供了多种强大的筛选方式,可以根据单个或多个条件从 DataFrame 中提取满足条件的数据行。

掌握数据筛选可以帮助你快速找到目标数据、过滤异常值、筛选特定时间段或特定类别的记录。


二、基本筛选语法

比较运算符筛选

使用比较运算符生成布尔 Series,然后用它来筛选 DataFrame。

代码示例

# 等于
df[df['列名'] == 值]

# 不等于
df[df['列名'] != 值]

# 大于/小于
df[df['列名'] > 值]
df[df['列名'] < 值]

# 大于等于/小于等于
df[df['列名'] >= 值]
df[df['列名'] <= 值]

使用 isin() 筛选

代码示例

# 筛选列值在指定列表中的行
df[df['列名'].isin(['值1', '值2', '值3'])]

# 取反:不在列表中的行
df[~df['列名'].isin(['值1', '值2'])]

使用 between() 筛选

代码示例

# 筛选在指定范围内的行(默认包含两端)
df[df['列名'].between(最小值, 最大值)]

# 不包含两端
df[df['列名'].between(最小值, 最大值, inclusive='neither')]

字符串筛选

代码示例

# 包含某字符串
df[df['列名'].str.contains('关键词')]

# 以某字符串开头
df[df['列名'].str.startswith('前缀')]

# 以某字符串结尾
df[df['列名'].str.endswith('后缀')]

# 正则表达式匹配
df[df['列名'].str.match(r'^[A-Z]')]

三、多条件组合筛选

组合多个条件时,需要使用 位运算符,而不是 Python 的逻辑运算符。

逻辑操作 pandas运算符 示例
与(AND) & df[(df['A'] > 0) & (df['B'] < 10)]
或(OR) | df[(df['A'] > 0) | (df['B'] < 10)]
非(NOT) ~ df[~(df['A'] > 0)]

重要提醒:每个条件必须用括号括起来!例如 df[(df['A'] > 0) & (df['B'] < 10)],不能写成 df[df['A'] > 0 & df['B'] < 10]


四、高级筛选方法

query() 方法

query() 提供了一种更简洁的筛选语法,特别适合复杂条件。

代码示例

# 使用query简化筛选
df.query('年龄 > 25 and 城市 == "北京"')

# 等同于
df[(df['年龄'] > 25) & (df['城市'] == '北京')]

# 使用变量
threshold = 20000
df.query('薪资 >= @threshold')

缺失值筛选

代码示例

# 筛选缺失值的行
df[df['列名'].isnull()]
df[df['列名'].isna()]

# 筛选非缺失值的行
df[df['列名'].notnull()]
df[df['列名'].notna()]

# 筛选所有列都非缺失的行
df.dropna()

# 筛选至少有一个缺失值的行
df[df.isnull().any(axis=1)]

重复值筛选

代码示例

# 筛选重复行
df[df.duplicated()]

# 筛选非重复行
df[~df.duplicated()]

# 按特定列筛选重复
df[df.duplicated(subset=['列1', '列2'])]

五、代码示例

示例1:创建示例数据

代码示例

import pandas as pd
import numpy as np

# 创建员工数据
df = pd.DataFrame({
    '姓名': ['张三', '李四', '王五', '赵六', '钱七', '孙八'],
    '年龄': [25, 30, 28, 35, 22, 40],
    '城市': ['北京', '上海', '广州', '深圳', '北京', '上海'],
    '部门': ['技术', '市场', '技术', '人事', '技术', '财务'],
    '薪资': [15000, 20000, 18000, 25000, 16000, np.nan],
    '入职年份': [2020, 2019, 2021, 2018, 2022, 2015]
})

print(df)
#    姓名  年龄  城市  部门       薪资  入职年份
# 0  张三  25  北京  技术  15000.0    2020
# 1  李四  30  上海  市场  20000.0    2019
# 2  王五  28  广州  技术  18000.0    2021
# 3  赵六  35  深圳  人事  25000.0    2018
# 4  钱七  22  北京  技术  16000.0    2022
# 5  孙八  40  上海  财务      NaN    2015

示例2:基本筛选

代码示例

# 筛选薪资大于18000的员工
print("=== 薪资 > 18000 ===")
print(df[df['薪资'] > 18000])

# 筛选技术部门的员工
print("\n=== 技术部门 ===")
print(df[df['部门'] == '技术'])

# 筛选城市在北京或上海的员工
print("\n=== 北京或上海 ===")
print(df[df['城市'].isin(['北京', '上海'])])

# 筛选年龄在25到35之间(包含)
print("\n=== 年龄25-35 ===")
print(df[df['年龄'].between(25, 35)]

输出:

代码示例

=== 薪资 > 18000 ===
   姓名  年龄  城市  部门       薪资  入职年份
1  李四  30  上海  市场  20000.0    2019
2  王五  28  广州  技术  18000.0    2021
3  赵六  35  深圳  人事  25000.0    2018

=== 技术部门 ===
   姓名  年龄  城市  部门       薪资  入职年份
0  张三  25  北京  技术  15000.0    2020
2  王五  28  广州  技术  18000.0    2021
4  钱七  22  北京  技术  16000.0    2022

=== 北京或上海 ===
   姓名  年龄  城市  部门       薪资  入职年份
0  张三  25  北京  技术  15000.0    2020
1  李四  30  上海  市场  20000.0    2019
4  钱七  22  北京  技术  16000.0    2022
5  孙八  40  上海  财务      NaN    2015

=== 年龄25-35 ===
   姓名  年龄  城市  部门       薪资  入职年份
0  张三  25  北京  技术  15000.0    2020
1  李四  30  上海  市场  20000.0    2019
2  王五  28  广州  技术  18000.0    2021
3  赵六  35  深圳  人事  25000.0    2018

示例3:多条件组合筛选

代码示例

# 技术部门且薪资大于16000
print("=== 技术部门 AND 薪资>16000 ===")
mask = (df['部门'] == '技术') & (df['薪资'] > 16000)
print(df[mask])

# 年龄小于25或大于35
print("\n=== 年龄<25 OR 年龄>35 ===")
print(df[(df['年龄'] < 25) | (df['年龄'] > 35)])

# 非技术部门
print("\n=== 非技术部门 ===")
print(df[~(df['部门'] == '技术')])

# 使用query
print("\n=== query方法 ===")
print(df.query('年龄 >= 25 and 城市 == "北京"'))

输出:

代码示例

=== 技术部门 AND 薪资>16000 ===
   姓名  年龄  城市  部门       薪资  入职年份
2  王五  28  广州  技术  18000.0    2021

=== 年龄<25 OR 年龄>35 ===
   姓名  年龄  城市  部门       薪资  入职年份
4  钱七  22  北京  技术  16000.0    2022
5  孙八  40  上海  财务      NaN    2015

=== 非技术部门 ===
   姓名  年龄  城市  部门       薪资  入职年份
1  李四  30  上海  市场  20000.0    2019
3  赵六  35  深圳  人事  25000.0    2018
5  孙八  40  上海  财务      NaN    2015

=== query方法 ===
   姓名  年龄  城市  部门       薪资  入职年份
0  张三  25  北京  技术  15000.0    2020

示例4:缺失值和重复值筛选

代码示例

# 筛选薪资缺失的行
print("=== 薪资缺失 ===")
print(df[df['薪资'].isnull()])

# 筛选薪资非缺失的行
print("\n=== 薪资非缺失 ===")
print(df[df['薪资'].notnull()])

# 使用query筛选缺失值
print("\n=== query筛选缺失值 ===")
print(df.query('薪资 != 薪资'))  # NaN != NaN 为 True

# 按城市筛选重复
print("\n=== 重复的城市 ===")
print(df[df.duplicated('城市', keep=False)])

六、实际应用场景

  • 异常值检测:筛选超出正常范围的数据进行审查或处理

  • 客户分群:根据消费金额、频率等条件筛选不同层级的客户

  • 时间筛选:筛选特定时间段内的交易记录或日志数据

  • 数据清洗:筛选缺失值、重复值、格式异常的数据进行清理


七、注意事项

注意1:多条件组合时,每个条件必须用括号括起来,且使用 &|~ 位运算符,而不是 and、or、not。

注意2:筛选返回的是视图或拷贝,直接修改可能触发 SettingWithCopyWarning。如果需要修改,建议先使用 .copy() 创建副本。

注意3:NaN(缺失值)在比较运算中始终返回 False。例如 df[df['薪资'] > 0] 会自动排除薪资为 NaN 的行。

小贴士

对于复杂的筛选条件,可以先将布尔条件赋值给变量,提高代码可读性。例如:

is_tech = df['部门'] == '技术'
high_salary = df['薪资'] > 20000
result = df[is_tech & high_salary]


八、筛选方法对比

方法 优点 缺点
布尔索引 灵活强大,支持所有运算符 条件多时代码冗长
query() 语法简洁,可读性高 不支持所有pandas方法
isin() 适合枚举值筛选 仅支持等于匹配
between() 范围筛选简洁 仅支持数值/日期范围
str.contains() 支持正则表达式 仅适用于字符串列
loc[条件] 可同时选择行列 语法相对复杂

九、小结

  • 基本筛选使用布尔索引:df[df['列'] > 值]

  • 多条件组合使用 &(与)、|(或)、~(非),每个条件需加括号

  • query() 提供更简洁的筛选语法,适合复杂条件

  • isin()、between()、str.contains() 是常用的高级筛选方法

  • 筛选修改数据时注意 SettingWithCopyWarning 警告


十、练习题

练习1

创建一个包含10条产品记录的DataFrame(产品名、类别、价格、销量、评分),筛选出:价格在100-500元之间、销量大于100、评分大于4.0的产品。

练习2

使用 query() 方法重写练习1的筛选条件,对比两种方式的代码可读性。

练习3

创建一个包含姓名(中文)和邮箱的DataFrame,使用 str.contains() 和正则表达式筛选出邮箱域名是 gmail.com 或 outlook.com 的用户。

常见问题

为什么不能用 and/or 而要用 &/|?

因为 df['列'] > 值 返回的是布尔 Series(数组),Python 的 and/or 无法处理数组级的逻辑运算。& 和 | 是逐元素的位运算符,可以对数组中的每个元素进行逻辑运算。

筛选后如何修改原DataFrame?

使用 loc 可以避免警告:df.loc[df['条件'], '列名'] = 新值。或者先创建副本:filtered = df[df['条件']].copy(),然后修改 filtered。

query() 和布尔索引哪个性能更好?

对于大数据集,query() 通常更快,因为它内部使用了 numexpr 优化引擎。对于小数据集,两者差异不明显。query() 的优势在于代码可读性。

如何筛选包含空字符串的行?

空字符串 '' 不等于 NaN。筛选空字符串:df[df['列'] == ''] 或 df[df['列'].str.len() == 0]。同时筛选空字符串和NaN:df[(df['列'] == '') | df['列'].isnull()]。

标签: 数据筛选 条件过滤 pandas教程 query方法 布尔索引 DataFrame

本文涉及AI创作

内容由AI创作,请仔细甄别

list快速访问

上一篇: pandas DataFrame选择数据 - loc与iloc详解 下一篇: pandas DataFrame增删改操作教程 - 数据添加删除修改详解

poll相关推荐