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

在大文件上应用FuzzyLogic时遇内存不足问题求助

解决FuzzyLogic处理大数据集时的内存不足问题

我太懂这种崩溃感了——小数据集跑起来顺风顺水,一搞大数据就爆内存,还弹出"Low memory Unable to create 6.6GB array"的提示。你的核心问题在于双重循环全量比对带来的巨量计算和内存开销,咱们一步步来优化,把这个问题解决掉。

先聊聊原代码的问题

  • 你写的双重循环for exp in exception_list套for orig in original_list,时间复杂度是O(n*m),当n和m都是几万甚至几十万级别的时候,不仅慢到离谱,中间生成的临时计算数据会直接把内存撑爆
  • 手动调用fuzz的三个方法,会重复计算字符串的相似度,造成冗余开销
  • difflib.get_close_matches每次都会遍历整个original_list,进一步加重内存负担

优化方案1:用FuzzyWuzzy的process.extractOne替代手动循环

FuzzyWuzzy的process模块内置了优化的匹配逻辑,extractOne会直接返回最匹配的结果,不需要你手动遍历整个列表,还能帮你减少重复计算。

修改后的核心代码:

from fuzzywuzzy import fuzz, process
import pandas as pd

# 读取数据的逻辑不变
df_To_beMatched = pd.read_excel('Vendor_file.xlsx', usecols=["VENDOR_NAME"])
df_To_beMatched['VENDOR_NAME'] = df_To_beMatched['VENDOR_NAME'].fillna('')
original_list = df_To_beMatched['VENDOR_NAME'].tolist()

df_exceptionlist = pd.read_excel('Exceptionfile.xlsx', usecols=["Entity_Name"])
df_exceptionlist['Entity_Name'] = df_exceptionlist['Entity_Name'].fillna('')
exception_list = df_exceptionlist['Entity_Name'].tolist()

result = []
for exp in exception_list:
    # 直接获取最匹配的结果,指定用token_set_ratio做评分
    match, token_score, _ = process.extractOne(exp, original_list, scorer=fuzz.token_set_ratio)
    # 再补充检查另外两个阈值
    ratio_score = fuzz.ratio(exp, match)
    partial_score = fuzz.partial_ratio(exp, match)
    
    if token_score > 75 and ratio_score > 75 and partial_score > 85:
        result.append({
            'Entity_Name': exp,
            'VENDOR_NAME': match,
            'Ratio': ratio_score,
            'Token': token_score,
            'Status': 'Match'
        })

# 保存结果
fuzzy_df = pd.DataFrame(result)
fuzzy_df.to_csv('FuzzyLogic_Results.csv', index=False)

优化方案2:分块处理数据集(内存救星)

如果你的数据集大到连加载到内存都困难,那就把数据切成小块,每次只处理一小块,处理完就释放内存,绝对不会爆内存。

示例代码:

from fuzzywuzzy import fuzz, process
import pandas as pd

def process_chunk(chunk_data, exception_list):
    chunk_results = []
    for exp in exception_list:
        match, token_score, _ = process.extractOne(exp, chunk_data, scorer=fuzz.token_set_ratio)
        ratio_score = fuzz.ratio(exp, match)
        partial_score = fuzz.partial_ratio(exp, match)
        
        if token_score > 75 and ratio_score > 75 and partial_score > 85:
            chunk_results.append({
                'Entity_Name': exp,
                'VENDOR_NAME': match,
                'Ratio': ratio_score,
                'Token': token_score,
                'Status': 'Match'
            })
    return chunk_results

# 分块读取原始数据,chunk_size根据你的内存情况调整,比如设为1000或5000
chunk_size = 1000
final_result = []

# 逐块处理
for chunk in pd.read_excel('Vendor_file.xlsx', usecols=["VENDOR_NAME"], chunksize=chunk_size):
    chunk['VENDOR_NAME'] = chunk['VENDOR_NAME'].fillna('')
    chunk_list = chunk['VENDOR_NAME'].tolist()
    chunk_result = process_chunk(chunk_list, exception_list)
    final_result.extend(chunk_result)

# 保存结果
fuzzy_df = pd.DataFrame(final_result)
fuzzy_df.to_csv('FuzzyLogic_Results.csv', index=False)

优化方案3:换成RapidFuzz(速度+内存双优化)

FuzzyWuzzy其实是基于RapidFuzz的旧封装,RapidFuzz用C++实现,速度快好几倍,内存占用还更低,API和FuzzyWuzzy几乎完全兼容,直接替换就行。

先安装:

pip install rapidfuzz

然后把导入部分改成:

from rapidfuzz import fuzz, process

其他代码完全不用改,你会发现不仅内存占用降下来了,运行速度也快了一大截。

优化方案4:给difflib瘦个身

如果你还需要保留difflib的结果,记得给get_close_matches加个n参数限制返回的匹配数量,避免生成太多结果占内存:

# 只返回前3个最匹配的结果,你可以根据需求调整
difflib_result = difflib.get_close_matches(to_delete, original_list, n=3)
matches = "^".join(difflib_result)
result_difflib.append({'Entity_Name': to_delete, 'Matches': matches})

如果不需要这部分结果,直接删掉能进一步减少内存消耗。

这些方法可以单独用,也可以组合起来(比如RapidFuzz+分块处理),应该能完美解决你的内存问题。

内容的提问来源于stack exchange,提问作者Python Explorer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 19:48:12