如何优化fuzzywuzzy模糊去重代码速度并保留rapidfuzz处理后的标点
模糊文本去重优化(提速+保留原始标点方案)
问题根因分析
- 标点丢失:你调用的
rapid_utils.default_process默认会移除所有非字母数字字符,且你最终导出的是预处理后的文本而非原始文本,因此标点全部被清除。 - 运行效率低:原有实现为O(n²)复杂度,逐行和全量数据集匹配,数据量超过1千行后耗时会指数级上升,2万行数据用该逻辑无法在合理时间内跑完。
优化方案
核心优化点
- 预处理仅用于相似度计算:自定义预处理规则,仅转小写、去多余空格,不删除标点,且预处理逻辑仅作为计算相似度的参数传入,全程保留原始文本用于输出。
- 匹配逻辑优化:改为增量匹配,每一条新文本仅和已经确认保留的非重复文本匹配,大幅降低匹配次数,复杂度从O(n²)降到O(n*m)(m为去重后的文本数量,远小于n)。
- 减少无效计算:给匹配接口设置
limit=2,仅返回前2个最高匹配结果,不需要全量返回匹配结果。 - 移除冗余逻辑:删除自行封装的Excel读取逻辑,直接用pandas内置的
read_excel接口,减少不必要的IO开销。
优化后完整代码
import pandas as pd from rapidfuzz.fuzz import token_set_ratio from rapidfuzz import process import time # 自定义预处理规则:仅转小写、去多余空格,不删除标点 def custom_processor(s): s = s.lower() return ' '.join(s.split()) threshold = 80 if __name__ == '__main__': t0 = time.time() # 读取原始数据 df = pd.read_excel(r'替换为你的输入文件路径.xlsx') # 去空值,转列表保留原始文本 data = df['Body'].dropna().tolist() clean_unique = [] for raw_text in data: # 第一条数据直接加入保留列表 if not clean_unique: clean_unique.append(raw_text) continue # 仅和已保留的非重复文本匹配,减少计算量 matches = process.extract( raw_text, clean_unique, scorer=token_set_ratio, processor=custom_processor, # 预处理仅用于相似度计算,不改动原始文本 score_cutoff=threshold, limit=2 # 仅取前2个匹配结果即可 ) if matches: # 存在匹配项时,保留更长的文本 matched_text = matches[0][0] if len(raw_text) > len(matched_text): clean_unique.remove(matched_text) clean_unique.append(raw_text) else: # 无匹配项直接加入保留列表 clean_unique.append(raw_text) # 导出结果,保留原始标点 clean_data = pd.DataFrame(clean_unique, columns=['Body']) clean_data.to_excel(r'替换为你的输出文件路径.xlsx', index=False) print(f'处理完成,原始数据共{len(data)}条,去重后共{len(clean_unique)}条,耗时{time.time()-t0:.2f}秒')
内容的提问来源于stack exchange,提问作者Shrumo
相关产品推荐
相关产品推荐

