如何高效修正含拼写错误的Excel产品名以匹配参考表?
优化模糊匹配效率解决超长时间运行问题
原代码的核心问题
你的代码在逻辑和效率上存在明显缺陷:
- 循环方向错误:遍历14000条参考数据,每条对3000条订单数据做全量模糊匹配,总计算量达4200万次,这是耗时的根本原因。
- 结果处理逻辑混乱:每次提取所有匹配结果后循环修改订单数据,同一个订单产品可能被多次覆盖,最终结果不可靠。
- 无意义的全量提取:
limit=order_1.shape[0]会返回所有匹配结果,完全没必要,浪费内存和计算时间。
优化方案
1. 替换高效的模糊匹配库
放弃fuzzywuzzy,改用rapidfuzz——它是fuzzywuzzy的C语言重写版本,速度可提升10-100倍。先安装:
pip install rapidfuzz pandas
2. 反转匹配方向+只取最佳匹配
改为遍历3000条订单数据,每条在14000条参考数据中找最佳匹配,而非反过来。这样逻辑更合理(每个订单产品对应一个最准确的参考名),且计算量相同但实际运行效率更高(只取Top1,无需处理冗余结果)。
3. 文本预处理(可选但推荐)
先对产品名做标准化处理,减少无效计算:
- 统一转为小写
- 去掉标点、空格、特殊符号
- 替换业务场景内的常见别名(比如将"维C"替换为"维生素C")
优化后的代码示例
import pandas as pd from rapidfuzz import process, fuzz # 读取数据 drug_list = pd.read_excel("drug_list.xlsx") order_1 = pd.read_excel("order-1.xlsx") # 文本预处理函数 def preprocess(text): if pd.isna(text): return "" # 统一小写、移除空格和标点 cleaned = text.lower().replace(" ", "").replace(".", "").replace(",", "") # 可添加更多业务相关替换规则 cleaned = cleaned.replace("维c", "维生素c") return cleaned # 对两表产品名做预处理 drug_list["cleaned_product"] = drug_list["product name"].apply(preprocess) order_1["cleaned_product"] = order_1["product name"].apply(preprocess) # 提取参考表的预处理后名称和原始正确名称 ref_cleaned = drug_list["cleaned_product"].tolist() ref_original = drug_list["product name"].tolist() # 遍历订单数据匹配最佳结果 matched_results = [] for prod in order_1["cleaned_product"]: if not prod: matched_results.append(None) continue # 直接过滤得分低于85的结果,只返回最佳匹配 best_match = process.extractOne( prod, ref_cleaned, scorer=fuzz.WRatio, # WRatio适配拼写错误、大小写差异场景 score_cutoff=85 ) if best_match: # 根据预处理名称找到原始正确名称 match_idx = ref_cleaned.index(best_match[0]) matched_results.append(ref_original[match_idx]) else: matched_results.append(None) # 赋值匹配结果并替换原字段(可选) order_1["matched_product_name"] = matched_results order_1["product name"] = order_1.apply( lambda x: x["matched_product_name"] if x["matched_product_name"] else x["product name"], axis=1 ) # 保存结果 order_1.to_excel("order-1_matched.xlsx", index=False)
进一步优化(超大数据量场景)
如果上述方法仍有压力,可以尝试:
- 分块匹配:将参考表按首字母或关键词分组,先通过简单字符串匹配过滤候选集,再做模糊匹配,减少每次匹配的候选数量。
- 向量化匹配:利用
rapidfuzz的process.cdist批量计算所有订单与参考产品的相似度矩阵,再提取每行最大值。
内容的提问来源于stack exchange,提问作者Mohamed Hammad
相关产品推荐
相关产品推荐

