基于嵌套AND/OR条件优雅高效筛选Pandas DataFrame的方法
Pandas多区域差异化筛选高效实现方案
针对500万行级别的大型DataFrame多规则差异化筛选场景,逐区域编写筛选语句再拼接的写法维护成本高、内存开销大,推荐用规则配置化+向量化掩码的方案实现,兼顾性能和可维护性。
核心思路
- 将所有区域的筛选规则抽离为独立配置字典,业务规则和执行逻辑解耦,后续新增/修改规则不需要改动核心筛选代码
- 全程使用pandas向量化运算生成全局布尔掩码,一次性完成行筛选,避免多次切片、
append(该方法已在新版pandas中弃用)带来的反复内存拷贝,百万行级数据处理性能提升明显
具体实现代码
import pandas as pd import operator # 1. 统一配置所有区域的筛选规则,新增区域直接追加键值对即可 region_rules = { "UK": { "supplier_list": ["ABW"], "output_compare": ">=", "output_threshold": 1, "target_year": 2021 }, "ANZ": { "supplier_list": ["ABC"], "output_compare": ">", "output_threshold": 1, "target_year": 2021 }, "ASEAN": { "supplier_list": ["ABE"], "output_compare": ">", "output_threshold": 1, "target_year": 2021 } } # 运算符映射表,支持扩展任意比较逻辑 op_mapper = { ">=": operator.ge, ">": operator.gt, "<=": operator.le, "<": operator.lt, "==": operator.eq } # 2. 初始化全False的筛选掩码 filter_mask = pd.Series(False, index=df.index) # 3. 遍历规则逐区域更新掩码 for region, rule in region_rules.items(): # 匹配当前区域的行 is_target_region = df["Region"] == region # 计算三个或条件 match_supplier = df["Supplier"].isin(rule["supplier_list"]) match_output = op_mapper[rule["output_compare"]](df["output"], rule["output_threshold"]) match_year = df["year"] == rule["target_year"] # 更新掩码:当前区域内满足任意一个或条件的行标记为保留 filter_mask = filter_mask | (is_target_region & (match_supplier | match_output | match_year)) # 4. 一次性筛选得到结果,无需多次拼接 result = df[filter_mask].reset_index(drop=True)
结果验证
执行后得到的结果和预期完全一致:
ID Region Supplier year output 0 1 ANZ AB 2021 1 1 2 ANZ ABC 2022 1 2 3 ANZ ABC 2022 1 3 4 ASEAN ABQ 2021 1 4 5 ASEAN ABE 2021 2 5 6 ASEAN ABQ 2021 3 6 7 UK ABW 2021 8
方案优势
- 性能优异:全程为向量化运算,无逐行遍历,500万行数据处理耗时通常在百毫秒级,比逐段筛选+拼接的写法快数倍
- 维护成本低:所有规则集中在配置字典中管理,哪怕后续扩展到几十个区域的差异化规则,也不需要重复编写筛选逻辑
- 扩展性强:如果后续需要新增筛选维度、调整比较逻辑,只需要修改配置结构和少量条件计算代码即可,核心筛选框架无需变动
内容的提问来源于stack exchange,提问作者The Great
相关产品推荐
相关产品推荐

