提升模糊匹配性能求助:200k+9k数据集匹配效率优化
优化大规模字符串模糊匹配的性能方案
你的代码跑慢的核心原因是:process.extract 默认对每个字符串都要和9k条记录做全量模糊匹配,200k * 9k = 1.8e9次计算,再加上fuzzywuzzy纯Python实现的低效,必然导致运行时间极长。以下是几个立竿见影的优化方案:
1. 替换为RapidFuzz(最快见效)
RapidFuzz是fuzzywuzzy的C++重写版本,API完全兼容,但速度能提升10-100倍,无需大幅修改代码:
from rapidfuzz import fuzz, process import pandas as pd df = pd.read_csv("你的数据文件.csv") list2 = df['comp'].tolist() list1 = df['var'].tolist() threshold = 90 # 仅替换导入包,其余逻辑不变 mat1 = [] for i in list1: # 可选:指定scorer为更快的算法,比如token_sort_ratio matches = process.extract(i, list2, limit=2, scorer=fuzz.token_sort_ratio, score_cutoff=threshold) mat1.append(matches) df['matches'] = mat1
2. 预过滤候选集,减少匹配次数
在做模糊匹配前,先通过简单规则过滤掉不可能匹配的候选,比如字符串长度差过大的:
from rapidfuzz import fuzz, process import pandas as pd df = pd.read_csv("你的数据文件.csv") list2 = df['comp'].tolist() list1 = df['var'].tolist() threshold = 90 # 设定长度差阈值,比如不超过±30% len_threshold = 0.3 mat1 = [] for i in list1: i_len = len(i) # 先过滤长度符合条件的候选 filtered_list = [s for s in list2 if abs(len(s) - i_len) <= i_len * len_threshold] if not filtered_list: mat1.append([]) continue matches = process.extract(i, filtered_list, limit=2, scorer=fuzz.token_sort_ratio, score_cutoff=threshold) mat1.append(matches) df['matches'] = mat1
如果是公司名这类文本,还可以用n-gram预筛选:先把所有字符串转换成n-gram特征,计算余弦相似度,只保留相似度高于某个阈值的候选再做模糊匹配,进一步减少计算量。
3. 多进程并行处理
利用CPU多核并行处理,把200k条任务拆分到多个进程:
from rapidfuzz import fuzz, process import pandas as pd from concurrent.futures import ProcessPoolExecutor df = pd.read_csv("你的数据文件.csv") list2 = df['comp'].tolist() list1 = df['var'].tolist() threshold = 90 def match_single(s): return process.extract(s, list2, limit=2, scorer=fuzz.token_sort_ratio, score_cutoff=threshold) # 用进程池并行处理,max_workers设为CPU核心数 with ProcessPoolExecutor(max_workers=4) as executor: mat1 = list(executor.map(match_single, list1)) df['matches'] = mat1
4. 选择更高效的匹配算法
不同模糊匹配算法的计算效率差异很大,根据你的场景选择:
- token_sort_ratio:适合公司名这类可能有词序差异的文本,计算速度比WRatio快
- partial_ratio:如果只需要部分匹配(比如简称匹配全称),速度更快
- 避免使用WRatio(fuzzywuzzy默认),它会尝试多种算法加权,计算成本最高
内容的提问来源于stack exchange,提问作者hilo
相关产品推荐
相关产品推荐

