我是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)
答案 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)
这样你每次都不会创建和存储一个大的新列表,只是保持你找到的最佳匹配,只有当你找到更好的匹配时才替换它。