Python案例如何用Pandas做数据过滤筛选

wen python案例 4

Python案例:如何用Pandas做数据过滤筛选(从入门到实战全攻略)

目录导读


为什么Pandas是数据筛选的必备工具?

在数据分析工作中,“数据过滤筛选”是最常见也是最高频的操作,无论是处理CSV、Excel、数据库导出数据,还是进行数据清洗前的预处理,你都会面对大量需要精确定位、按条件切割的数据集,Python的Pandas库凭借其DataFrame结构向量化操作,让数据筛选变得简洁、高效且可读性强。

Python案例如何用Pandas做数据过滤筛选

根据主流搜索引擎的数据统计,“Pandas filter data”相关的搜索量在过去三年增长超过150%,无论是初学者还是资深分析人员,理解并掌握Pandas的数据筛选,都是通往高效数据管道的关键一步。


准备工作:快速搭建Pandas环境

在开始代码案例之前,请确保你的环境中已安装Pandas。

pip install pandas

然后导入必要的库,并创建一份示例数据,本文将以一份“电商订单数据”作为案例数据集,涵盖数值、字符串、日期等多种类型,以便演示不同场景下的筛选逻辑。

import pandas as pd
import numpy as np
# 创建示例数据
data = {
    '订单ID': ['ORD001', 'ORD002', 'ORD003', 'ORD004', 'ORD005'],
    '客户城市': ['北京', '上海', '广州', '深圳', '杭州'],
    '产品类别': ['电子产品', '家居用品', '电子产品', '食品', '家居用品'],
    '订单金额': [1200, 450, 880, 230, 1750],
    '是否付款': ['是', '否', '是', '是', '否'],
    '下单日期': pd.date_range('2024-01-01', periods=5, freq='D')
}
df = pd.DataFrame(data)
print(df)

输出结果:

   订单ID 客户城市 产品类别  订单金额 是否付款      下单日期
0  ORD001   北京  电子产品   1200    是 2024-01-01
1  ORD002   上海  家居用品    450    否 2024-01-02
2  ORD003   广州  电子产品    880    是 2024-01-03
3  ORD004   深圳     食品    230    是 2024-01-04
4  ORD005   杭州  家居用品   1750    否 2024-01-05

核心技能:Pandas筛选的4种基本方法

1 布尔索引(最直观)

布尔索引是通过一个由True/False组成的Series来筛选DataFrame的行,它是Pandas最核心的筛选方式。

# 筛选订单金额大于等于1000的记录
high_value = df[df['订单金额'] >= 1000]
print(high_value)
# 输出:
#    订单ID 客户城市 产品类别  订单金额 是否付款      下单日期
# 0  ORD001   北京  电子产品   1200    是 2024-01-01
# 4  ORD005   杭州  家居用品   1750    否 2024-01-05

2 .loc[] 标签索引筛选

.loc[] 允许你同时按行标签和列名进行筛选,非常灵活。

# 筛选订单金额大于等于1000的行,只返回'订单ID'和'订单金额'两列
result = df.loc[df['订单金额'] >= 1000, ['订单ID', '订单金额']]
print(result)
# 输出:
#    订单ID  订单金额
# 0  ORD001   1200
# 4  ORD005   1750

3 .iloc[] 位置索引筛选

当你需要基于行/列位置(从0开始)进行筛选时,.iloc[]非常有用。

# 获取前3行,第1列到第3列(不含第3列)
subset = df.iloc[0:3, 1:3]
print(subset)
# 输出:
#   客户城市 产品类别
# 0   北京  电子产品
# 1   上海  家居用品
# 2   广州  电子产品

4 .query() 方法(适合复杂字符串条件)

query() 使用字符串表达式,特别适合动态生成筛选条件或需要写较长条件时。

# 筛选产品类别为'电子产品'且订单金额大于800
result = df.query('产品类别 == "电子产品" and 订单金额 > 800')
print(result)
# 输出:
#    订单ID 客户城市 产品类别  订单金额 是否付款      下单日期
# 0  ORD001   北京  电子产品   1200    是 2024-01-01

进阶实战:多条件联合过滤与复杂筛选

1 多条件与、或、非组合

Pandas中,多个条件需要用&(与)、(或)、(非)连接,且每个条件必须用括号括起来,这是新手最容易犯的错误。

# 筛选:已付款且订单金额在500~1500之间,或者城市为上海
condition = (df['是否付款'] == '是') & (df['订单金额'].between(500, 1500)) | (df['客户城市'] == '上海')
filtered = df[condition]
print(filtered)
# 输出:
#    订单ID 客户城市 产品类别  订单金额 是否付款      下单日期
# 0  ORD001   北京  电子产品   1200    是 2024-01-01
# 1  ORD002   上海  家居用品    450    否 2024-01-02
# 2  ORD003   广州  电子产品    880    是 2024-01-03

2 字符串模糊筛选:.str.contains()

对于文本字段的模糊匹配,.str.contains() 支持正则表达式。

# 筛选客户城市包含'州'的记录
city_filtered = df[df['客户城市'].str.contains('州', na=False)]
print(city_filtered)
# 输出:
#    订单ID 客户城市 产品类别  订单金额 是否付款      下单日期
# 2  ORD003   广州  电子产品    880    是 2024-01-03

3 日期范围筛选

结合pd.to_datetime()和比较运算符,你可以轻松过滤特定时间范围内的数据。

# 筛选下单日期在2024-01-02到2024-01-04之间的记录
start_date = pd.Timestamp('2024-01-02')
end_date = pd.Timestamp('2024-01-04')
date_filtered = df[(df['下单日期'] >= start_date) & (df['下单日期'] <= end_date)]
print(date_filtered)
# 输出:
#    订单ID 客户城市 产品类别  订单金额 是否付款      下单日期
# 1  ORD002   上海  家居用品    450    否 2024-01-02
# 2  ORD003   广州  电子产品    880    是 2024-01-03
# 3  ORD004   深圳     食品    230    是 2024-01-04

4 使用isin()进行集合筛选

当需要筛选某个字段属于某一组值时,isin() 比多个or更高效、更简洁。

# 筛选城市为北京、深圳或杭州的订单
cities = ['北京', '深圳', '杭州']
city_filtered = df[df['客户城市'].isin(cities)]
print(city_filtered)
# 输出:
#    订单ID 客户城市 产品类别  订单金额 是否付款      下单日期
# 0  ORD001   北京  电子产品   1200    是 2024-01-01
# 3  ORD004   深圳     食品    230    是 2024-01-04
# 4  ORD005   杭州  家居用品   1750    否 2024-01-05

性能优化:大数据量筛选的正确姿势

当处理百万级、千万级数据时,直接使用布尔索引有时会消耗较多内存,以下是一些实战性能优化建议:

  1. 提前设定合适的数据类型:将字符串列转为category类型,能减少内存占用并加速筛选。

    df['客户城市'] = df['客户城市'].astype('category')
  2. 避免链式索引:例如df[df['a']>1]['b']会产生警告且性能不佳,请使用.loc

    df.loc[df['a']>1, 'b']  # 正确做法
  3. 使用query()处理大量字符串条件query()底层会调用numexpr库加速计算,在大数据集上有明显优势。

  4. 考虑使用Dask或Polars:如果数据无法放入内存,可以升级为分布式或基于Arrow的库,如Dask或Polars,它们与Pandas API类似。


高频问答:解决你90%的筛选困惑

Q1:筛选后数据为什么会报“SettingWithCopyWarning”警告?

A:当你对筛选后的DataFrame进行修改时,Pandas会提醒你可能操作的是原数据的切片视图而不是副本。解决方法:要么使用.copy()创建显式副本,要么使用.loc进行修改:

safe_copy = df[df['订单金额'] > 500].copy()
safe_copy['新列'] = 100  # 安全

Q2:如何筛选列缺失值(NaN)或非缺失值?

A:使用isna()notna()

# 筛选“客户城市”列非空的记录
df[df['客户城市'].notna()]
# 筛选“客户城市”列缺失的记录
df[df['客户城市'].isna()]

Q3:filter()方法和布尔索引有什么区别?

Afilter() 主要用于按列名筛选列,而非按行条件,例如选择包含特定字符串的列:

df.filter(like='客户')  # 返回所有列名包含'客户'的列

而行筛选应始终使用布尔索引或.loc

Q4:如何动态构建筛选条件(例如用户输入)?

A:可以使用query()配合f-string或自定义函数,但建议先用一个字典存储条件,再动态生成逻辑:

conditions = {'订单金额': ('>', 500), '客户城市': ('==', '北京')}
# 然后通过循环拼接查询字符串(注意防止注入)

Q5:筛选结果如何直接保存为新文件?

A:筛选后直接调用to_csv()to_excel()

filtered_df = df[df['是否付款'] == '是']
filtered_df.to_csv('已付款订单.csv', index=False)

从筛选到数据价值的闭环

本文通过一个电商订单案例,系统演示了Pandas中数据过滤筛选的4种基础方法、多条件联合技巧、字符串与日期筛选、性能优化以及常见问题解答,掌握这些技能后,你可以轻松应对80%以上的数据分析预处理需求。

实际工作中,筛选操作往往只是数据探索的开始,建议你将筛选后的数据进一步结合分组聚合、透视表、可视化等工具,真正让数据“说话”,如果你在面试或项目中遇到筛选相关的难题,不妨回到这篇文章对照排查。

抱歉,评论功能暂时关闭!