如何基于客户字符串列表筛选DataFrame中不匹配的行?
筛选不包含指定客户的账单行
现有两个DataFrame:
- 账单DataFrame(
fct):CONTENTS列是格式不统一的客户相关字符串 - 客户名单DataFrame(
cust):存储需要排除的目标客户名称
需求:从fct中筛选出CONTENTS列不包含cust中任何客户名称的行。
初始数据代码
import pandas as pd fct = pd.DataFrame({'NUMBIL':[858, 863, 870, 871, 872, 880, 881], 'DATE':['01/01/23', '01/01/23', '01/01/23', '07/01/23', '07/01/23', '08/01/23', '08/01/23'], 'CONTENTS':['Billed to HENRY', 'VIKTOR', 'Regard to ALEX', 'MARK 01*', 'To charge SAMANTHA every Thursday', 'VIKTOR LECOMTE', '****'], 'AMOUNT':['25$', '96$', '13$', '96$', '96$', '13$', '13$'], }) cust = pd.DataFrame({'CUSTOMERS':['VIKTOR', 'ALEX', 'SAMANTHA'], })
方案1:正则表达式批量匹配(高效简洁)
把客户名单拼接成正则匹配模式,一次性完成筛选,适合数据量较大的场景:
# 生成匹配所有客户的正则模式,用|分隔多个匹配项 pattern = '|'.join(cust['CUSTOMERS']) # 用~取反,筛选不包含任何客户名的行 result = fct[~fct['CONTENTS'].str.contains(pattern)] print(result)
注:如果需要忽略大小写匹配,可添加参数
case=False
方案2:逐行检查所有客户(直观易懂)
通过apply逐行判断该行是否不包含所有客户名,逻辑清晰,适合新手理解:
# 定义判断函数:当行内CONTENTS不包含任何客户名时返回True def is_excluded(row): return all(customer not in row['CONTENTS'] for customer in cust['CUSTOMERS']) result = fct[fct.apply(is_excluded, axis=1)] print(result)
方案3:分步标记筛选(灵活可调)
先为每个客户生成存在标记,再基于标记筛选,方便后续扩展其他逻辑:
# 为每个客户生成是否存在的标记列 for customer in cust['CUSTOMERS']: fct[f'contains_{customer}'] = fct['CONTENTS'].str.contains(customer) # 筛选所有标记均为False的行(即不包含任何客户) result = fct[~fct[[f'contains_{c}' for c in cust['CUSTOMERS']]].any(axis=1)] # 清理临时生成的标记列 result = result.drop(columns=[f'contains_{c}' for c in cust['CUSTOMERS']]) print(result)
预期输出
NUMBIL DATE CONTENTS AMOUNT 0 858 01/01/23 Billed to HENRY 25$ 3 871 07/01/23 MARK 01* 96$ 6 881 08/01/23 **** 13$
内容的提问来源于stack exchange,提问作者Laurent B.
相关产品推荐
相关产品推荐

