Python中两个高相似名称列表的模糊匹配优化及结果输出问题
模糊匹配优化方案及实现代码
现有代码核心问题
- 嵌套循环效率低,当
actual_name量级大时运行耗时极高 - 仅取第一个满足阈值的匹配项,未对比所有匹配项的得分,容易错过更优匹配
- 未存储匹配得分,无法对结果做二次校验
- 使用字典存储匹配结果,若
sample_name存在重复值会被覆盖 - 代码存在笔误:
response.item()应为response.items()
优化思路
- 文本预处理:统一字符格式,去掉公司后缀、特殊符号等无关内容,降低匹配干扰
- 最优匹配逻辑:为每个
sample_name计算所有actual_name的匹配得分,取得分最高的结果 - 效率优化:直接使用fuzzywuzzy内置的
process.extractOne方法,替代手动嵌套循环 - 多指标加权(可选):组合多种fuzz匹配算法的得分,进一步提升匹配准确率
优化后代码
import pandas as pd from fuzzywuzzy import fuzz, process # 文本预处理函数,可根据自身数据情况调整规则 def preprocess_name(name): # 统一转小写 name = name.lower() # 去除常见公司后缀 suffix_list = ['llc', 'inc.', 'inc', 'ltd', 'co.', 'co'] for suffix in suffix_list: name = name.replace(suffix, '') # 仅保留字母、数字、空格 name = ''.join([c for c in name if c.isalnum() or c.isspace()]) # 去除首尾空格和多余中间空格 return ' '.join(name.split()) # 预处理两个列表的名称 sample_names = sample_df['sample_name'].tolist() actual_names = actual_df['actual_name'].tolist() preprocessed_actual = [preprocess_name(name) for name in actual_names] # 存储匹配结果 match_results = [] # 匹配得分阈值,低于该阈值的结果视为无效匹配,可自行调整 SCORE_THRESHOLD = 70 for sample in sample_names: preprocessed_sample = preprocess_name(sample) # 提取得分最高的匹配项,scorer可根据需求替换为fuzz.token_set_ratio等 best_match, score = process.extractOne( preprocessed_sample, preprocessed_actual, scorer=fuzz.WRatio, score_cutoff=SCORE_THRESHOLD ) # 映射回原actual_name original_actual = actual_names[preprocessed_actual.index(best_match)] if best_match else None match_results.append({ 'sample_name': sample, 'actual_name': original_actual, 'match_score': score if best_match else 0 }) # 生成最终三列DataFrame result_df = pd.DataFrame(match_results) print(result_df)
额外调优建议
- 如果匹配准确率仍不符合预期,可以尝试更换
scorer参数:fuzz.token_set_ratio更适合存在词序颠倒的场景,fuzz.partial_ratio更适合短名称匹配长名称的场景 - 可以对多个scorer的得分做加权平均,再取最高值,进一步降低误匹配概率
- 若
actual_name量级超过10万,可搭配rapidfuzz库替代fuzzywuzzy,运算速度提升10倍以上,接口完全兼容无需修改代码
内容的提问来源于stack exchange,提问作者Derek Henderson
相关产品推荐
相关产品推荐

