本文目录导读:
Python 数据筛选是一个非常基础且高频的操作,尤其在数据分析、数据清洗和机器学习特征工程中,下面我将按照工具类型(基础语法、Pandas、NumPy)和典型场景,为你整理一些常用的数据筛选案例。
基础 Python 语法筛选 (适合小规模数据)
假设我们有一个包含字典的列表,代表数据行。
# 模拟数据
students = [
{"name": "Alice", "age": 22, "score": 88, "city": "Beijing"},
{"name": "Bob", "age": 25, "score": 72, "city": "Shanghai"},
{"name": "Charlie", "age": 19, "score": 95, "city": "Beijing"},
{"name": "David", "age": 30, "score": 60, "city": "Guangzhou"},
{"name": "Eve", "age": 21, "score": 85, "city": "Shanghai"},
]
# 案例1: 使用列表推导式筛选 (大于80分的学生)
high_score = [s for s in students if s["score"] > 80]
print("高分学生:", high_score)
# 案例2: 多个条件 (年龄小于22且来自北京)
young_beijing = [s for s in students if s["age"] < 22 and s["city"] == "Beijing"]
print("年轻北京学生:", young_beijing)
# 案例3: 使用 filter 函数 (筛选及格的)
passing = list(filter(lambda s: s["score"] >= 60, students))
print("及格学生:", passing)
Pandas 数据筛选 (最常见、最强大)
Pandas 是 Python 数据科学的标配工具,以下案例基于 DataFrame 结构。
import pandas as pd
# 创建 DataFrame
df = pd.DataFrame({
"Name": ["Alice", "Bob", "Charlie", "David", "Eve"],
"Age": [22, 25, 19, 30, 21],
"Score": [88, 72, 95, 60, 85],
"City": ["Beijing", "Shanghai", "Beijing", "Guangzhou", "Shanghai"]
})
# --- 核心筛选技巧 ---
# 1. 布尔索引 (最常用)
# 筛选 Score > 80 的行
filtered = df[df["Score"] > 80]
print("高分同学:\n", filtered)
# 2. 多条件组合 (用 & | ~ 括号)
# 筛选 年龄 < 25 且 分数 >= 85
result = df[(df["Age"] < 25) & (df["Score"] >= 85)]
print("年轻学霸:\n", result)
# 或条件: 来自 Beijing 或 Shanghai
result_or = df[(df["City"] == "Beijing") | (df["City"] == "Shanghai")]
print("一线城市学生:\n", result_or)
# 3. isin() 方法 (适用于“在某个集合中”)
# 筛选城市为 Beijing 或 Shanghai 的更简洁写法
cities = ["Beijing", "Shanghai"]
result_isin = df[df["City"].isin(cities)]
print("使用isin:\n", result_isin)
# 4. between() 方法 (范围筛选)
# 筛选年龄在 20 到 25 之间 (包含边界)
age_range = df[df["Age"].between(20, 25)]
print("20-25岁学生:\n", age_range)
# 5. 字符串筛选 (str.contains / startswith)
# 筛选名字包含 "li" (不区分大小写)
name_filter = df[df["Name"].str.contains("li", case=False)]
print("名字含li:\n", name_filter)
# 筛选城市以 "Shang" 开头
city_start = df[df["City"].str.startswith("Shang")]
print("Shang开头的城市:\n", city_start)
# 6. 查询空值 (isnull / notna)
df_with_na = df.copy()
df_with_na.loc[2, "Score"] = None # 制造一个空值
missing_score = df_with_na[df_with_na["Score"].isnull()]
print("分数缺失的学生:\n", missing_score)
# 7. query() 方法 (类似SQL风格,推荐)
# 用字符串表达式筛选
query_result = df.query("Age > 20 and City == 'Beijing'")
print("Query筛选:\n", query_result)
# 传变量用 @
min_age = 22
dynamic_query = df.query("Age >= @min_age and Score > 80")
print("动态筛选:\n", dynamic_query)
NumPy 筛选 (适合数值型数组)
通常用于数值计算或机器学习数据预处理。
import numpy as np
arr = np.array([[1, 2, 3],
[4, 5, 6],
[7, 8, 9]])
# 1. 布尔索引 (返回一维数组)
greater_than_5 = arr[arr > 5]
print("大于5的元素:", greater_than_5) # 输出 [6 7 8 9]
# 2. 多条件 (用 & |)
condition = (arr > 2) & (arr < 8)
filtered_arr = arr[condition]
print("2到8之间的元素:", filtered_arr) # 输出 [3 4 5 6 7]
# 3. where() 函数 (返回条件为True的索引)
indices = np.where(arr > 5)
print("大于5的元素索引:", indices) # 索引元组
print("对应值:", arr[indices])
# 4. 筛选行或列 (二维数组)
# 筛选第二列大于5的行
row_filter = arr[arr[:, 1] > 5]
print("第二列>5的行:\n", row_filter) # 输出 [[7 8 9]]
综合案例:经典数据分析场景
场景 1:电商订单分析
orders = pd.DataFrame({
"OrderID": range(1, 6),
"Amount": [100, 250, 50, 300, 150],
"Status": ["Delivered", "Pending", "Cancelled", "Delivered", "Pending"],
"City": ["A", "B", "A", "C", "B"]
})
# 目标:筛选已交付且金额大于200的订单
result = orders[(orders["Status"] == "Delivered") & (orders["Amount"] > 200)]
print("高价值已交付订单:\n", result)
场景 2:股票价格分析
dates = pd.date_range("2024-01-01", periods=5)
stock = pd.DataFrame({
"Date": dates,
"Price": [100, 102, 98, 105, 107],
"Volume": [1000, 1200, 800, 1500, 900]
})
# 目标:筛选价格在100以上且交易量大于1000的天数
# 方法1:布尔索引
high_price_high_vol = stock[(stock["Price"] > 100) & (stock["Volume"] > 1000)]
print(high_price_high_vol)
# 方法2:查询
print(stock.query("Price > 100 and Volume > 1000"))
场景 3:复杂条件 + 时间筛选
data = pd.DataFrame({
"Date": pd.date_range("2024-01-01", periods=10, freq="D"),
"Value": np.random.randint(50, 100, 10)
})
data.set_index("Date", inplace=True)
# 筛选 2024-01-03 到 2024-01-07 之间的数据
date_filter = data.loc["2024-01-03":"2024-01-07"]
print("时间范围筛选:\n", date_filter)
# 筛选 Value > 80 且在指定日期范围内
complex_filter = data.loc["2024-01-01":"2024-01-05"][data["Value"] > 80]
print("复杂条件:\n", complex_filter)
高性能筛选技巧
如果数据量非常大(百万级以上),以下方法可以提高速度:
- 使用
.loc代替直接df[condition]:.loc更明确,且在某些情况下更高效。 - 使用 NumPy 数组转换:
df.values转为数组操作后,再映射回 DataFrame。 - 使用
pd.eval():适合大型 DataFrame 的布尔表达式计算。 - 避免链式赋值:使用
.loc[row, col]一次性修改。
怎么选?
| 场景 | 推荐方法 |
|---|---|
| 小型数据 (< 1000行) | 列表推导式、Pandas 基本布尔索引 |
| 中型数据 (10万行以内) | Pandas .query()、布尔索引、.isin() |
| 大型数据 (百万及以上) | Pandas + 优化技巧 (.eval, .values)、Dask、PySpark (Spark) |
| 纯数值计算 | NumPy |
| 模糊匹配 / 文本 | .str.contains(), .str.startswith() |
如果你有具体的业务场景(如“如何筛选连续上涨的股票?”、“如何筛选异常值?”),欢迎继续追问,我可以给你针对性的代码示例。
标签: Python