2013-12-08 167 views
3

我想使用Python 2.7和Levenshtein函数将姓氏列表匹配到全名列表。为了减少工作量,我只在第一个字母相同的情况下才会匹配(尽管这在性能上似乎没有太大区别)。如果找到匹配项,则从全名中删除匹配的词(以使后续的名字匹配更容易)。这两个列表都包含几万个条目,所以我的解决方案相当慢。我如何在不解析完整名称的情况下加快速度? 这里是我迄今为止(对于情况下,我省略了一些,如果条件在lastnames由若干字):Python,嵌套循环,匹配和性能

import Levenshtein 

listoflastnames=(['Jones', 'Sallah']) 
listoffullnames=(['Henry', 'Jones', 'Junior'],['Indiana', 'Jones']) 


def match_strings(lastname, listofnames): 
    match=0 
    matchedidx=[] 
     for index, nameelement in enumerate(listofnames):   
      if lastname[0]==nameelement [0]: 
       if Levenshtein.distance(nameelement, lastname)<2: 
        matchedidx.append(index) 
        match=match+1 
    if match==1: 
     newnamelist = [i for j, i in enumerate(listofnames) if j not in matchedidx] 
    return 1, newnamelist 
return 0, listofnames 



for x in listoflastnames: 
    for y in listoffullnames: 
     match, newlistofnames=match_strings(x,y) 
     if match==1: 
      #go to first name match... 

任何帮助,将不胜感激!

更新:在此期间,我使用了多处理模块让我的所有4核处理问题而不仅仅是一个,但匹配仍需要很长时间。

+0

'Levenshtein.distance(G,publastnames [0]' 什么是G和publastnames [0]这里? – M4rtini

+0

对不起,那是一个遗留的从旧版本。在莱文斯坦功能比较姓和一个字 – MrFancypants

+1

如果只打算执行第一个字母相同的计算,则可能需要将列表拆分为第一个字母索引的字典,然后您可以执行只有可行的候选人之间进行比较,而不是所有人之间的比较,这是否会提高性能取决于花在这个开销上的时间是多少,而不是距离计算的结果 – DSM

回答

1

这简化了match_string函数中的for循环,但在我的测试中并没有显着提高速度。最大的损失是在带有姓氏和全名的两个for循环中。

def match_strings(lastname, listofnames): 
    firstCaseMatched = [name for name in listofnames if lastname[0] == name[0]] 
    if len(firstCaseMatched): 
     matchedidx = [index for index, ame in enumerate(firstCaseMatched) if Levenshtein.distance(lastname, name) < 2] 
     match = len(matchedidx) 
    else: 
     match = 0 
    if match == 1: 
     newnamelist = [i for j, i in enumerate(listofnames) if j not in matchedidx] 
     return 1, newnamelist 
    return 0, listofnames 

您可能需要进行排序知姓氏的名单,他们分成dict每个起始字符。然后将名称列表中的每个名称与该名称进行匹配。

假设全名列表始终具有作为第一个元素的名字。您可以将比较限制为仅限其他元素。

+0

感谢您的所有建议。我已经把姓氏分成一个字典,其中第一个字母是建议的键。与多处理一起,该脚本现在的速度是原始版本的20倍。 – MrFancypants

+0

顺便说一句,我假设你使用Levenshtein距离,因为名称可能拼写错误?你能确定名字中的第一个字母是正确的吗? – M4rtini

+0

我无法确定,但是当我测试脚本时未排除第一个字母与我的数据子集相匹配的情况时,似乎引入了大量误报。因为我必须从结果集中手动删除误报,所以我愿意接受略低的召回率:) – MrFancypants