You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

优化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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 21:50:05