如何基于字典与模式匹配优化信用卡交易分类(替代np.select)
替代np.select()的简洁信用卡交易分类实现
问题背景
当前通过字典结合np.select()实现信用卡交易描述的分类,但需要手动关联字典键、匹配条件和分类选项,存在冗余。需要更简洁的实现方式,避免嵌套循环和重复代码。
解决方案1:反向映射+正则提取
通过构建关键词到分类的反向映射,配合pandas字符串提取方法,一次性完成分类匹配,无需手动编写每个条件:
import pandas as pd def cat_mapper(frame, targ_col, cat_col): # 定义分类-关键词字典 category_retailers = { 'Online Shopping': ['amazon','amzn mktp', 'target.com'], 'Wholesale Stores': ['costco', 'target'], } # 构建反向映射:关键词 → 对应分类 keyword_to_cat = {} for category, keywords in category_retailers.items(): for kw in keywords: keyword_to_cat[kw] = category # 构建不区分大小写的正则匹配模式 regex_pattern = '|'.join([f'(?i){kw}' for kw in keyword_to_cat.keys()]) # 提取匹配的关键词并映射为分类,未匹配的保留原分类值 frame[cat_col] = ( frame[targ_col] .str.extract(f'({regex_pattern})', expand=False) .map(keyword_to_cat) .fillna(frame[cat_col]) ) return frame
解决方案2:按优先级批量匹配赋值
通过遍历分类字典,利用布尔掩码批量更新未分类的行,逻辑直观且便于调整分类优先级(先遍历的分类会优先匹配):
import pandas as pd def cat_mapper(frame, targ_col, cat_col): category_retailers = { 'Online Shopping': ['amazon','amzn mktp', 'target.com'], 'Wholesale Stores': ['costco', 'target'], } # 遍历分类,仅更新未分类的行 for category, keywords in category_retailers.items(): # 构建当前分类的匹配掩码 match_mask = frame[targ_col].str.contains( '|'.join(keywords), regex=True, case=False ) # 仅更新原分类为空(NaN)的行 update_mask = match_mask & frame[cat_col].isna() frame.loc[update_mask, cat_col] = category return frame
测试代码
使用提供的样例数据测试(注意先将字符串'NaN'转为真实的缺失值,避免干扰匹配):
data_dict = { 'Description': ['amazon 345689','amzn mktp online 7765','amazon 4444','costco location','Wholefoods'], 'Category': ['NaN','NaN','NaN','NaN','Groceries'] } df = pd.DataFrame(data_dict) # 将字符串'NaN'转为pandas缺失值 df['Category'] = df['Category'].replace('NaN', pd.NA) # 调用分类函数 result_df = cat_mapper(df, 'Description', 'Category') print(result_df)
方案对比
- 方案1:代码紧凑,一次性完成映射,适合分类规则简单、无优先级需求的场景
- 方案2:逻辑清晰,支持按顺序设置分类优先级(若某交易匹配多个分类,先遍历的分类生效),便于后续规则调整
内容的提问来源于stack exchange,提问作者canconfirm24
相关产品推荐
相关产品推荐

