在数据处理和分析中,pandas 是一个非常强大的工具,它提供了灵活高效的数据结构,能够轻松处理各种数据操作,筛选行数据是日常工作中最常用的操作之一,掌握这一技能可以大大提高数据处理的效率,本文将详细介绍如何使用 pandas 筛选行数据,涵盖多种方法和实际应用场景。

基本筛选方法:基于布尔条件
pandas 最基础的行筛选方式是通过布尔条件实现,假设我们有一个 DataFrame df,想要筛选出满足特定条件的行,可以直接在方括号中传入一个布尔数组,筛选出某列值大于特定数值的所有行:
import pandas as pd
# 示例数据
data = {'A': [1, 2, 3, 4, 5],
'B': [10, 20, 30, 40, 50]}
df = pd.DataFrame(data)
# 筛选列A大于3的行
filtered_df = df[df['A'] > 3]
这种方法的核心在于生成一个布尔数组,df['A'] > 3 会返回一个与 DataFrame 行数相同的 Series,其中每个元素是 True 或 False,pandas 会自动保留 True 对应的行。
多条件筛选:逻辑运算符的运用
在实际应用中,常常需要同时满足多个条件,此时可以使用逻辑运算符 &(与)、(或)和 (非),需要注意的是,布尔运算符必须用括号包围,以避免优先级问题。
# 筛选列A大于3且列B大于20的行 filtered_df = df[(df['A'] > 3) & (df['B'] > 20)]
这里,& 表示两个条件必须同时满足,如果希望满足其中一个条件即可,可以使用 。 用于取反,例如筛选出列A不大于3的行:
filtered_df = df[~(df['A'] > 3)]
使用 query() 方法简化条件表达式
当条件较为复杂时,直接书写布尔表达式可能会显得冗长,pandas 提供了 query() 方法,允许使用类似 SQL 的语法进行筛选。
# 使用query方法筛选
filtered_df = df.query('A > 3 and B > 20')
query() 方法支持字符串表达式,语法更简洁,尤其适合多列条件或复杂逻辑。query() 还可以引用外部变量,只需在变量名前添加 符号:
threshold = 3
filtered_df = df.query('A > @threshold')
基于 isin() 的多值筛选
如果需要筛选某列值在给定列表中的所有行,可以使用 isin() 方法,这在处理分类数据或离散值时非常实用。

# 筛选列A值在[2, 4]中的行 filtered_df = df[df['A'].isin([2, 4])]
isin() 返回一个布尔 Series,表示每个元素是否在指定列表中,如果需要排除列表中的值,可以在 isin() 前加上 。
使用 loc 和 iloc 进行精确筛选
loc 和 iloc 是 pandas 中用于基于标签或位置索引的强大工具。loc 基于行标签和列标签进行筛选,而 iloc 基于整数位置。
# 使用loc筛选行标签为1和3的行 filtered_df = df.loc[[1, 3]] # 使用iloc筛选第1行和第3行(从0开始计数) filtered_df = df.iloc[[1, 3]]
结合布尔条件,loc 可以实现更灵活的筛选:
# 使用loc筛选列A大于3的行 filtered_df = df.loc[df['A'] > 3]
处理缺失值:dropna() 和 fillna() 筛选
在数据清洗过程中,常常需要处理缺失值(NaN),可以使用 dropna() 筛选出不含缺失值的行:
# 筛选出所有列都没有缺失值的行 filtered_df = df.dropna()
如果只想在特定列上检查缺失值,可以指定 subset 参数:
# 筛选出列A没有缺失值的行 filtered_df = df.dropna(subset=['A'])
相反,如果需要保留含缺失值的行,可以使用 fillna() 填充缺失值后再筛选,或直接使用 isna() 进行条件筛选:
# 筛选出列A含缺失值的行 filtered_df = df[df['A'].isna()]
高级技巧:使用 eval() 提升性能
对于大型 DataFrame,eval() 可以通过优化布尔表达式的计算来提升性能,它类似于 query(),但更侧重于计算而非筛选:

# 使用eval优化筛选
filtered_df = df[df.eval('A > 3 and B > 20')]
eval() 会尝试优化表达式,减少中间变量的内存占用,适合处理复杂或大规模数据。
实际应用场景示例
假设我们有一个销售数据 DataFrame,需要筛选出“销售额大于1000且地区为‘华东’”的记录:
sales_data = {'销售额': [1200, 800, 1500, 900, 2000],
'地区': ['华东', '华南', '华东', '华北', '华东']}
sales_df = pd.DataFrame(sales_data)
# 筛选符合条件的记录
high_sales_east = sales_df[(sales_df['销售额'] > 1000) & (sales_df['地区'] == '华东')]
通过结合布尔条件,可以灵活应对多种业务需求。
相关问答 FAQs
问题1:如何高效筛选大型 DataFrame 中的行?
解答:对于大型 DataFrame,建议使用 query() 或 eval() 方法,它们能优化表达式计算并减少内存占用,避免链式操作(如多次筛选),尽量将条件合并为一步,以提升性能。
问题2:如何在筛选行时保留原始索引?
解答:默认情况下,筛选后的 DataFrame 会保留原始索引,如果希望重置索引,可以使用 reset_index(drop=True),drop=True 表示丢弃原索引。
filtered_df = df[df['A'] > 3].reset_index(drop=True)