如何提升Python模糊匹配大Excel文件的运行速度?
大文件模糊匹配提速咨询
我的Python代码处理小Excel(约30条数据)时运行正常,耗时约1分钟。现在要处理两个大文件,分别有3688条和26959条数据,逻辑是加载两个Excel,提取Matching String列,用fuzzywuzzy的token_set_ratio做模糊匹配后导出结果。但大文件运行5分钟还没完成,求提速方法,或者是否该拆分文件处理?
import os import pandas as pd from fuzzywuzzy import fuzz # 文件路径 filename = r"C:\Users\user\Desktop\AddressTest4.xlsx" filename1 = r"C:\Users\user\Desktop\CertsExcel.xlsx" # 加载Excel文件 companyA = pd.read_excel(filename, sheet_name = "Address String Match") companyB = pd.read_excel(filename1, sheet_name = "ExtractExcelFiles") # 生成客户列表 A = [customer for customer in companyA["Matching String"]] B = [customer for customer in companyB["Matching String"]] # 模糊匹配并找出最高分匹配项 tuples_list = [max([(fuzz.token_set_ratio(i.lower(),j.lower()),j) for j in A]) for i in B] similarity_score, fuzzy_match = map(list,zip(*tuples_list)) # 创建DataFrame并导出 df = pd.DataFrame({"Original Name": B, "Matching Name": fuzzy_match, "similarity score":similarity_score}) df.to_excel(r"C:\Users\user\Desktop\Fuzz Test3.xlsx", sheet_name="Fuzzy Match3", index=False)
提速方案
替换fuzzywuzzy为RapidFuzz
fuzzywuzzy是纯Python实现,性能有限。RapidFuzz是它的C语言重写版本,速度能提升10-100倍。安装后直接替换导入即可:from rapidfuzz import fuzz原有代码逻辑无需修改,性能会大幅提升。
提前预处理字符串
把所有字符串提前转小写、去除多余空格或特殊字符,避免在循环中重复执行这些操作:# 预处理字符串:去空值、转小写、去首尾空格 A = [str(cust).strip().lower() for cust in companyA["Matching String"].dropna()] B = [str(cust).strip().lower() for cust in companyB["Matching String"].dropna()] # 匹配时直接用预处理后的结果,省去重复转换 tuples_list = [max([(fuzz.token_set_ratio(i,j),j) for j in A]) for i in B]优化匹配逻辑,减少不必要计算
可以加入提前终止条件,比如匹配到满分直接返回,或者过滤低于阈值的项:def find_best_match(target, candidates, threshold=80): best_score = 0 best_candidate = None for cand in candidates: score = fuzz.token_set_ratio(target, cand) if score > best_score: best_score = score best_candidate = cand # 拿到满分直接结束循环 if best_score == 100: return (best_score, best_candidate) # 当前最高分已远超阈值,后续分数差距大时提前终止 if best_score > threshold and score < best_score - 10: break return (best_score, best_candidate) tuples_list = [find_best_match(i, A) for i in B]使用批量计算工具
用RapidFuzz的process.cdist批量计算相似度矩阵,配合多CPU核心并行处理,比单循环快很多:from rapidfuzz import process, utils # 用RapidFuzz的工具预处理字符串 processed_A = [utils.default_process(s) for s in A] processed_B = [utils.default_process(s) for s in B] # 批量计算相似度矩阵,workers=-1启用所有CPU核心 scores = process.cdist(processed_B, processed_A, scorer=fuzz.token_set_ratio, workers=-1) # 提取每个目标的最高分和对应匹配项 max_indices = scores.argmax(axis=1) similarity_score = scores.max(axis=1) fuzzy_match = [A[idx] for idx in max_indices]关于拆分文件
拆分文件是可行的,但属于退而求其次的方案——把B分成多个小批次,分别和A匹配后合并结果。不过前面的性能优化能带来更显著的提速,优先尝试上述方法。
内容的提问来源于stack exchange,提问作者EfrenS
相关产品推荐
相关产品推荐

