Python 使用 Pandas 筛选 Excel 数据并剔除区间外值
基于 Python 的 Pandas 库读取 Excel 或 CSV 文件,通过布尔索引逻辑筛选特定列的数据范围,剔除不符合条件的行,并将结果保存为新文件。本文介绍了静态条件筛选、动态配置筛选及 query 方法三种实现方式,涵盖环境配置、错误处理、NaN 值处理及性能优化建议,适用于各类数据清洗场景。

基于 Python 的 Pandas 库读取 Excel 或 CSV 文件,通过布尔索引逻辑筛选特定列的数据范围,剔除不符合条件的行,并将结果保存为新文件。本文介绍了静态条件筛选、动态配置筛选及 query 方法三种实现方式,涵盖环境配置、错误处理、NaN 值处理及性能优化建议,适用于各类数据清洗场景。

在数据处理与分析的实际工作中,经常需要清理无效或异常数据。例如,传感器采集的读数可能因设备故障超出物理合理范围,或者图像特征值不符合预期的分布规律。为了保证后续模型训练或分析结果的准确性,我们需要一种方法来自动识别并删除这些不符合指定区间的数据行,仅保留有效样本。
本文将详细介绍如何使用 Python 强大的数据分析库 Pandas 高效完成这一任务,涵盖基础筛选、动态配置、查询方法以及异常处理等完整流程。
首先,确保开发环境中已安装 Pandas 库。如果尚未安装,可通过 pip 命令进行安装:
pip install pandas openpyxl
其中 pandas 用于核心数据处理,openpyxl 是支持 .xlsx 格式读写所需的引擎。
最直接且易于理解的方式是对每一列分别应用过滤条件,然后取逻辑交集。这种方法逻辑直观,适合规则较少且固定的场景。
import pandas as pd
# 定义文件路径(建议使用相对路径)
input_path = 'data/input.csv'
output_path = 'data/output_filtered.csv'
# 读取数据
try:
df = pd.read_csv(input_path)
except FileNotFoundError:
raise Exception("输入文件不存在")
# 依次应用筛选条件
# 假设 inf 列需要在 -0.2 到 18 之间
# 注意:Pandas 中必须使用 & 表示'且',不能用 and
df = df[(df["inf"] >= -0.2) & (df["inf"] <= 18)]
# 假设 NDVI 列需要在 -1 到 1 之间
df = df[(df["NDVI"] >= -1) & (df["NDVI"] <= 1)]
# 其他列同理,例如 soil 列需大于等于 0
df = df[(df["soil"] >= 0)]
# 保存结果
# index=False 避免保存行索引
df.to_csv(output_path, index=False)
print(f"筛选完成,共剩余 {len(df)} 行数据")
& 表示逻辑与,| 表示逻辑或,不能使用 Python 原生的 and/or,否则会报错。(df["col"] > 0),否则会导致运算优先级错误。当需要筛选的列较多且规则相似时,硬编码多个链式语句会显得冗长且难以维护。我们可以使用字典来存储列名和对应的上下限规则,通过循环动态生成过滤条件。
import pandas as pd
def filter_dataframe(df, rules):
"""
根据规则字典动态筛选 DataFrame
:param df: 原始 DataFrame
:param rules: 字典,格式 {列名:[最小值,最大值]}
:return: 筛选后的 DataFrame
"""
# 初始化全真掩码
mask = pd.Series([True] * len(df), index=df.index)
for col, limits in rules.items():
if col not in df.columns:
print(f"警告:列 '{col}' 不存在,跳过")
continue
min_val, max_val = limits
# 构建当前列的布尔掩码
# 处理无上界情况(max_val 为 None)
if max_val is None:
col_mask = df[col] >= min_val
else:
col_mask = (df[col] >= min_val) & (df[col] <= max_val)
# 合并掩码
mask = mask & col_mask
return df[mask]
# 定义筛选规则
filter_rules = {
"inf": (-0.2, 18),
"NDVI": (-1, 1),
"soil": (0, None), # None 表示无上界限制
}
# 执行筛选
filtered_df = filter_dataframe(df, filter_rules)
filtered_df.to_csv('result.csv', index=False)
此方法的优势在于维护方便,只需修改 filter_rules 字典即可调整筛选逻辑,无需改动核心代码结构,非常适合规则频繁变更的场景。
Pandas 提供了 query() 方法,允许使用字符串表达式进行筛选,代码可读性更强,且底层通常利用 numexpr 引擎优化计算。
# 使用 query 方法,语法类似 SQL
df = df.query("-0.2 <= inf <= 18 and -1 <= NDVI <= 1 and soil >= 0")
@ 符号前缀,如 @min_val。query 通常比布尔索引稍快。在实际工程中,数据文件可能存在缺失列、类型不匹配或空值等问题。建议在代码中加入异常捕获机制以确保程序稳定运行。
import pandas as pd
import numpy as np
def safe_filter(input_path, output_path, rules):
try:
# 读取数据
df = pd.read_csv(input_path)
# 预处理:填充或删除缺失值
# 此处选择将数值列的 NaN 视为不满足条件从而被剔除
# 或者先填充再筛选,视业务逻辑而定
# 应用筛选
filtered_df = filter_dataframe(df, rules)
# 保存结果
filtered_df.to_csv(output_path, index=False)
print(f"筛选完成,原始行数:{len(df)}, 剩余行数:{len(filtered_df)}")
except FileNotFoundError:
print("错误:找不到输入文件")
except KeyError as e:
print(f"错误:数据集中缺少列 {e}")
except Exception as e:
print(f"发生未知错误:{e}")
chunksize 参数分块读取处理,避免内存溢出。虽然本文主要演示 CSV 格式,但 Pandas 同样支持 .xlsx 格式。
若需保存为 Excel:
filtered_df.to_excel('result.xlsx', index=False)
通过 Pandas 的布尔索引、动态配置或 query 方法,我们可以灵活地剔除 Excel 或 CSV 文件中不在指定区间的数据。选择哪种方法取决于规则的复杂度和数据规模。对于常规任务,链式索引足够;对于复杂规则,动态配置更为优雅;对于追求性能的场景,可尝试 query 或分块处理。掌握这些技巧将大幅提升数据清洗的效率与质量。

微信公众号「极客日志」,在微信中扫描左侧二维码关注。展示文案:极客日志 zeeklog
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
将 Markdown(GFM)转为 HTML 片段,浏览器内 marked 解析;与 HTML转Markdown 互为补充。 在线工具,Markdown转HTML在线工具,online
将 HTML 片段转为 GitHub Flavored Markdown,支持标题、列表、链接、代码块与表格等;浏览器内处理,可链接预填。 在线工具,HTML转Markdown在线工具,online