提高模糊比的速度

时间:2016-05-04 14:59:59

标签: python python-3.x

我是python的新手,正在努力加速这段代码。

我在zz1中有大约100万个字符串,在a3中有250,000个字符串。 zz1中的字符串中有错误,我想将它匹配到a3中的字符串,a3具有最高的模糊匹配率。

我对结果很满意,但在zz1中处理一行大约需要9秒。有没有办法加快速度?

import csv
import string
import time
import sys
from fuzzywuzzy import fuzz
op=[]
for i in range(1,len(zz1)):
    num=zz1[i][1] 
    start2 = time.clock()
    forecast = []

    if not num in zz4 and zz5:

       for j in range (1,len(a3)):
           forecast.append(fuzz.ratio(num,a3[j][1]))

       if (max(forecast)>60):
           index=forecast.index(max(forecast))
           op.append(a3[index][1])

    elapsed2 = (time.clock() - start2)    
    print (i,elapsed2)

2 个答案:

答案 0 :(得分:1)

由于数据代表缩写字符串而不是拼写错误或其他错误,因此您应该能够通过消除简单的选择来执行此操作。

考虑这两个例子(我不知道GRAND CANYON会如何缩写,所以这只是一个猜测来说明这一点):

GRAND CANYON    -> GR CANYON
MELBOURNE REEF  -> MELBRNE REEF

GR CANYON无法与MELBOURNE REEF相关,因此无需测试。按字符串的左前缀分组来编码此测试,您应该看到非常高的命中率,因为缩写通常会保留第一个字母。

因此,您只比较以“G”开头的缩写与以“G”开头的全名,以及“M”以“M”开头等等。

另请注意,这不一定要提供完美匹配;您将保留不匹配字符串列表并在找到匹配项时删除匹配项,因此在比较分组字符串并删除匹配项后,您的最终不匹配项列表将是原始数据的一小部分,可以是使用您原来的蛮力方法相对较快地进行比较

只使用第一个字符,您可以将每个列表中要比较的字符串数减少26倍,从而将比较次数减少26 * 26,即快676倍!

由于在初始消除步骤中不需要完美的准确性,因此您可以将此分组扩展到不仅仅是第一次迭代的第一个字符,减少每个额外迭代的字符数,直到达到零个字符。使用2个字符的分组,您可以将每个列表中的项目数减少26 * 26,从而将比较总数减少26 * 26 * 26 * 26,或从2500亿减少到大约50万个比较。使用3个字符的分组,从2500亿到大约809。

通过使用这种迭代方法,您将在不失去准确性的情况下执行指数级更少的模糊操作。

答案 1 :(得分:0)

不知道这会节省多少时间,但这一点似乎不必要地复杂化了:

for j in range (1,len(a3)):
    forecast.append(fuzz.ratio(num,a3[j][1]))

if (max(forecast)>60):
    index=forecast.index(max(forecast))
    op.append(a3[index][1])

每次,你正在创建一个包含250,000个元素的新列表,然后你要检查max元素的新列表,然后你找到该max元素的索引来从中检索相关值原始清单。做更多的事情可能更有意义:

max_ratio = 0
match = ''
for a in a3:
    fr = fuzz.ratio(num,a[1])
    if fr > max_ratio:
        max_ratio = fr
        match = a[1]
if max_ratio > 60:
    op.append(match)

这样你每次都不会创建和存储一个大的新列表,只是保持你找到的最佳匹配,只有当你找到更好的匹配时才替换它。