基于规则表条件为pandas DataFrame新增分类列的实现方案咨询
实现方案
核心思路
用预解析规则+全向量化匹配实现,完全避开循环遍历行操作,百万行数据可在秒级完成匹配,同时完美适配规则表的NaN跳过逻辑。
实现步骤
- 第一步:预处理规则表,拆分每一条规则的精确匹配条件、模糊匹配关键词、对应分类结果,保留规则的原始顺序(匹配优先级和规则表行顺序一致,先出现的规则优先命中)
- 第二步:遍历每一条规则,动态构造向量化的布尔匹配条件,全程使用pandas原生API,不使用字符串拼接后eval的不安全低性能方案
- 第三步:用
numpy.select批量完成所有规则的匹配,无匹配结果自动填充NaN
代码实现
import pandas as pd import numpy as np def my_function(rules_table: pd.DataFrame, data_table: pd.DataFrame) -> pd.DataFrame: cond_list = [] choice_list = [] # 提取除了Category和Description之外的精确匹配字段 exact_cols = [col for col in rules_table.columns if col not in ['Category', 'Description']] for _, rule_row in rules_table.iterrows(): # 构造当前规则的初始条件(全为True) current_cond = pd.Series([True]*len(data_table), index=data_table.index) # 遍历精确匹配字段,跳过NaN值 for col in exact_cols: rule_val = rule_row[col] if pd.notna(rule_val): current_cond &= (data_table[col] == rule_val) # 处理Description的包含匹配,跳过NaN desc_keyword = rule_row['Description'] if pd.notna(desc_keyword): # 关键词是普通字符串的话加regex=False大幅提升速度 current_cond &= data_table['Description'].str.contains(desc_keyword, regex=False) cond_list.append(current_cond) choice_list.append(rule_row['Category']) # 批量匹配,无匹配返回NaN data_table['Category'] = np.select(cond_list, choice_list, default=np.nan) return data_table
性能优化建议
- 如果规则数量超过100条,可先按精确字段的唯一组合对规则分组,同一组合下的多个Description关键词合并为正则表达式,一次性完成匹配,减少
str.contains的调用次数 - 若数据量超过千万行,可将精确匹配字段拼接为一个哈希键,用字典映射先完成第一层快速过滤,再对剩余少量数据做模糊匹配
- 若规则表中存在互斥的规则,可按规则覆盖范围排序,高覆盖规则放前面,提前命中减少后续条件判断
内容的提问来源于stack exchange,提问作者Mikkel Miqlliot Lehmann
相关产品推荐
相关产品推荐

