You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于嵌套列表的多组关键词批量过滤DataFrame文本列

批量实现DataFrame多组关键词过滤方案

核心规则:每个关键词子列表对应一条过滤逻辑,要求transaction_description字段同时命中组内所有关键词,通过动态生成布尔掩码即可完成批量过滤,无需手动硬编码每个关键词判断。

方法1:逐组遍历判断(可读性最高,适配绝大多数场景)

先完成测试数据与依赖初始化:

import pandas as pd
from pandas import Timestamp

# 初始化待处理DataFrame
df_data = [
    [5,  56,  Timestamp('2022-01-29 00:00:00'),  'pac c.misalud conv. unificado',  12320.0],
    [5,  57,  Timestamp('2021-12-19 00:00:00'),  'cargo seguro proteccion bancaria',  31222.0], 
    [5,  60,  Timestamp('2021-04-06 00:00:00'),  'pac sura cia seguros generales',  8657.0],
    [5,  178,  Timestamp('2022-03-21 00:00:00'),  'cargo seguro proteccion bancaria',  31222.0], 
    [5,  179,  Timestamp('2022-03-01 00:00:00'),  'pac c.misalud conv. unificado',  12320.0], 
    [5,  182,  Timestamp('2022-03-15 00:00:00'),  'pac sura cia seguros generales',  8657.0],
    [5,  189,  Timestamp('2022-04-21 00:00:00'),  'cargo seguro proteccion bancaria',  31222.0],
    [5,  190,  Timestamp('2022-04-01 00:00:00'),  'pac c.misalud conv. unificado',  12320.0],
    [5,  193,  Timestamp('2022-04-15 00:00:00'),  'pac sura cia seguros generales',  8657.0],
    [5,  206,  Timestamp('2022-05-21 00:00:00'),  'cargo seguro proteccion bancaria',  31222.0],
    [5,  256,  Timestamp('2022-06-17 00:00:00'),  'cargo seguro proteccion bancaria',  40222.0]
]
kw_df = pd.DataFrame(df_data, columns=['user_id', 'reg_id', 'date', 'transaction_description', 'value'])

# 从MySQL读取的嵌套关键词配置
keywords = [
    [('tarifa',), ('mantenimiento',), ('mensual',)],  
    [('tasa',), ('anual',)],    
    [('seguro',), ('bancaria',)],  
    [('seguro',), ('generales',)],  
    [('mi salud',), ('unific',)]
]

核心过滤逻辑:

all_matched = []

for rule_id, kw_group in enumerate(keywords):
    # 提取当前规则组内的关键词(适配单元素元组的存储结构)
    current_kws = [kw[0] for kw in kw_group]
    # 初始化布尔掩码为全True,逐关键词做逻辑与运算
    mask = pd.Series(True, index=kw_df.index)
    for kw in current_kws:
        mask &= kw_df['transaction_description'].str.contains(kw, case=False)
    # 过滤得到当前规则命中的行,追加规则ID便于后续区分
    group_res = kw_df[mask].copy()
    group_res['match_rule_id'] = rule_id
    all_matched.append(group_res)

# 合并所有命中结果,若存在同一行命中多条规则的情况会保留多条记录
final_result = pd.concat(all_matched, ignore_index=True)

基于提供的测试数据运行后,会命中3组规则:

  • 规则ID2(seguro+bancaria):匹配所有cargo seguro proteccion bancaria记录
  • 规则ID3(seguro+generales):匹配所有pac sura cia seguros generales记录
  • 规则ID4(mi salud+unific):匹配所有pac c.misalud conv. unificado记录
    规则ID0、ID1无匹配数据,返回空结果,和手动硬编码的过滤逻辑完全一致。

方法2:正则合并优化(适配10万行以上大数据量场景)

逐关键词调用str.contains会产生多次字符串遍历开销,数据量较大时可将每组关键词拼接为正向预查正则,仅需一次字符串匹配即可完成判断:

import re

all_matched = []
for rule_id, kw_group in enumerate(keywords):
    current_kws = [kw[0] for kw in kw_group]
    # 拼接为同时匹配所有关键词的正则,re.escape自动转义正则特殊字符
    pattern = '^' + ''.join([f'(?=.*{re.escape(kw)})' for kw in current_kws])
    mask = kw_df['transaction_description'].str.contains(pattern, case=False, regex=True)
    group_res = kw_df[mask].copy()
    group_res['match_rule_id'] = rule_id
    all_matched.append(group_res)

final_result = pd.concat(all_matched, ignore_index=True)

正则逻辑说明:(?=.*关键词)为正向零宽预查,代表字符串任意位置存在对应关键词,多个预查项拼接即代表同时满足所有关键词存在的要求。

常用配置调整

  • 若需关键词匹配区分大小写,将str.contains的参数case=False改为case=True即可
  • 若需匹配完整单词而非子串(例如避免seguro匹配到seguros),可在关键词两侧添加\b词边界标记,按需调整正则规则即可
  • 若仅需返回所有命中的行、不需要区分命中的规则组,合并结果时添加final_result = final_result.drop_duplicates(subset=['user_id','reg_id'])即可去重

内容的提问来源于stack exchange,提问作者feruciform

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 08:03:28