如何在fuzzywuzzy中避免循环匹配?DataFrame匹配场景解决方案
解决模糊匹配中的循环重复问题
问题背景
现有如下DataFrame:
import pandas as pd df = pd.DataFrame( dict(Name=['Emma Howard', 'Emma Ward', 'Emma Warner', 'Emma Wayden'], Age=[33, 34, 43, 44], Score=[90, 95, 93, 92]) )
使用fuzzywuzzy的process.extractBests方法处理姓名列时,出现循环匹配问题:比如Emma Howard和Emma Ward会互相出现在对方的匹配结果里。需求是实现:已匹配过的条目,不再出现在后续行的匹配结果中。
原伪代码的问题在于每次循环后重置了候选列表,没有真正移除已匹配的条目,无法达到预期效果。
解决方案
核心思路是维护一个动态更新的可用候选列表,每次完成匹配后,将已配对的条目从候选列表中永久移除,避免后续重复匹配。
完整代码
import pandas as pd from fuzzywuzzy import process, fuzz # 初始化DataFrame df = pd.DataFrame( dict(Name=['Emma Howard', 'Emma Ward', 'Emma Warner', 'Emma Wayden'], Age=[33, 34, 43, 44], Score=[90, 95, 93, 92]) ) # 初始化可用候选姓名列表,复制原始姓名列表 available_names = df['Name'].tolist().copy() matches_list = [] for current_name in df['Name']: # 先移除当前姓名,避免匹配自身 available_names.remove(current_name) # 提取当前姓名的最优匹配(仅保留分数≥80的结果) best_matches = process.extractBests( current_name, available_names, score_cutoff=80, scorer=fuzz.ratio ) matches_list.append(best_matches) # 如果有匹配结果,将匹配到的姓名从可用列表中移除,防止后续重复匹配 if best_matches: # extractBests返回的是(匹配姓名, 匹配分数)的元组,取第一个匹配的姓名 matched_name = best_matches[0][0] available_names.remove(matched_name) # 将匹配结果添加到DataFrame df['matches'] = matches_list # 保存到CSV文件 df.to_csv("xyz.csv", index=False)
代码逻辑说明
- 动态候选列表:
available_names初始包含所有姓名,后续会随着匹配操作不断剔除已使用的条目 - 避免自匹配:遍历每个姓名时,先将当前姓名从候选列表中移除,确保不会匹配到自己
- 移除已匹配条目:每次得到最优匹配后,立即将该匹配条目从候选列表中删除,后续循环不会再将其作为候选
- 结果存储:将每一行的匹配结果存入列表,最后添加到DataFrame并导出为CSV
预期效果
运行后,Emma Howard匹配到Emma Ward后,Emma Ward在后续遍历过程中,候选列表里已经没有Emma Howard,不会再生成互相匹配的结果;同理其他配对也只会出现一次。
内容的提问来源于stack exchange,提问作者Kingston X
相关产品推荐
相关产品推荐

