优化Pandas大数据框模糊匹配代码,缩短运行时长
DataFrame大规模数据模糊匹配优化方案
问题场景
我有两个DataFrame:dataframeA(20万行)和dataframeB(8.3万行)。需要比对两表的city与name列,当city一致且name相同或近似时,计算匹配率,并生成包含两表所有列的dataframeC。当前代码在小样本下可正常运行,但全量运行时(仅取dataframeB的2000行就耗时1小时)速度过慢,原代码如下:
import pandas as pd import spacy import string # pour charger une librairie de ponctuation (string.punctuation) from fuzzywuzzy import fuzz from fuzzywuzzy import process city_city = set(dataframeA['CODE city']).intersection(set(dataframeB['Code city'])) result_rows = [] def calculate_match_percentage(str1, str2): return fuzz.ratio(str1.lower(), str2.lower()) for city in city_city: result_selection = dataframeA[dataframeA['CODE city'] == city] categorie_selection = dataframeB[dataframeB['Code city'] == city] for index_A, row_A in result_selection.iterrows(): for index_B, row_B in categorie_selection.iterrows(): A_string = str(row_A['name']) B_string = str(row_B['name']) match_percentage = calculate_match_percentage(A_string.lower(), B_string.lower()) if match_percentage > 80: result_dict = {col: row_A[col] for col in dataframeA.columns} result_dict.update({col: row_B[col] for col in dataframeB.columns}) result_dict["match"] = match_percentage # Ajouter le pourcentage de match result_rows.append(result_dict)
原代码慢的核心原因
- 嵌套循环效率极低:两层
iterrows遍历属于逐行操作,加上同city下的笛卡尔积比对,时间复杂度呈指数级增长 - 重复计算冗余:每次循环都重复执行字符串转小写、模糊匹配计算,没有提前预处理
- 内存操作低效:逐行构建字典再追加列表,内存占用大且拼接速度慢
优化方案
1. 提前标准化字符串,减少重复计算
先对两表的name列做统一格式化处理,避免在循环中重复操作:
def clean_name(s): # 统一转小写,可按需添加标点移除、停用词过滤等规则 s = str(s).lower() # 可选:移除标点 # s = s.translate(str.maketrans('', '', string.punctuation)) return s # 预处理两表的name列 dataframeA['clean_name'] = dataframeA['name'].apply(clean_name) dataframeB['clean_name'] = dataframeB['name'].apply(clean_name)
2. 按City合并表,缩小比对范围
先通过city列做内连接,只保留同city的行对,避免跨city的无效比对:
# 先统一两表的city列名(原代码中A是CODE city,B是Code city) dataframeB.rename(columns={'Code city': 'CODE city'}, inplace=True) # 按city做内连接,得到同city下的所有A-B行配对 merged = pd.merge(dataframeA, dataframeB, on='CODE city', how='inner', suffixes=('_A', '_B'))
3. 向量化计算匹配率,替代嵌套循环
用apply向量化操作替代逐行循环,大幅提升运算速度:
from fuzzywuzzy import fuzz # 批量计算所有配对行的匹配率 merged['match'] = merged.apply(lambda row: fuzz.ratio(row['clean_name_A'], row['clean_name_B']), axis=1) # 过滤匹配率大于80的结果 dataframeC = merged[merged['match'] > 80] # 移除预处理的临时列,保留原表所有字段 dataframeC = dataframeC.drop(columns=['clean_name_A', 'clean_name_B'])
4. 替换更快的模糊匹配库(可选)
如果fuzzywuzzy速度仍不够,换成rapidfuzz(fuzzywuzzy的C语言实现,速度提升10-100倍):
# 先安装:pip install rapidfuzz from rapidfuzz import fuzz merged['match'] = merged.apply(lambda row: fuzz.ratio(row['clean_name_A'], row['clean_name_B']), axis=1)
5. 内存优化(可选)
对重复值多的列设置为category类型,减少内存占用提升运算效率:
dataframeA['CODE city'] = dataframeA['CODE city'].astype('category') dataframeB['CODE city'] = dataframeB['CODE city'].astype('category')
内容的提问来源于stack exchange,提问作者Marie Ducourau
相关产品推荐
相关产品推荐

