为列表理解中的循环嵌套矢量化



我有两个字符串列表,用于计算Damerau–Levenstein距离以检查哪些相似。我列出的问题超过了20万,经过理解,这需要相当长的时间。对于距离计算,我使用的是用Cython编写的pyxDamerauLevenstein包,所以应该没有瓶颈

series = ([damerau_levenshtein_distance(i, j) for i in original_string for j in compare_string])

这就是我的代码的样子,我想知道它是否可以以某种方式进行矢量化以提高性能,或者以其他方式加快计算速度?

什么是我的数据集:

原始字符串-它是pd。一系列独特的街道名称

比较字符串-这是pd。我想比较的一系列手动输入的街道名称,以查找相似性

输出应该是这样的:

Original    Compare   Distance
0  Street1     Street1      1
1  Street2     Street1      2
2  Street3     Street1      3
3  Street4     Street3      5
4  Street5     Street3      5
5  Street6     Street6      1

如果你能想到一种使用map(或imap(函数而不是嵌套循环的方法,那么你可以尝试使用多处理来充分利用你的CPU。例如,在这种情况下:

pool.map(lambda j: map(lambda i: damerau_levenshtein_distance(i, j),original_string),compare_string) 

其中"pool.map"是多处理映射,第二个"map"是常规映射。

下面是一个快速但实用的多处理示例,它可以涵盖您正在寻找的内容。我对它的结构有点不同,以避免一些酸洗问题,并使它在后台异步计算,因为您的列表很长
(这肯定可以改进,但希望能为您的示例提供概念证明(

import multiprocessing as mp
import itertools
list1 = range(5)
list2 = range(5)
def doSomething(a,b):
return a+b #Your damerau_levenshtein_distance function goes here
def mapDoSomething(args):
i = args[0] #An element of list2
otherlist = args[1] #A copy of list1
return [doSomething(i,j) for j in otherlist]
if __name__ == '__main__':
pool = mp.Pool()
answer = pool.imap(mapDoSomething,zip(list2,itertools.repeat(list1)))
print(list(answer)) #imap will compute the results in the background whilst the rest of the code runs. You can therefore ask for individual lists of results, and it won't block unless the result hasn't been computed yet. To do this, you would use answer.next() or iterate over the results somewhere else. However, by converting to a list here, I'm forcing all results to finish before printing. This is only to show you it worked. For larger lists, don't do this.
pool.close()
pool.join()

此代码生成:

[[0,1,2,3,4],[1,2,3,4,5],[2,3,4,5,6],[3,4,5,6,7],[4,5,6,7,8]]

这是list1的每个元素与list2的每个元素一起操作(我添加了它们(,我认为这是您在代码中尝试使用字符串列表所做的。

该代码设置了进程池,然后使用imap将list2上的操作处理拆分为多个进程。zip函数将list2的元素与list1的完整副本惰性地分组,因为imap只支持具有单个参数的函数。然后,这个组被拆分并用于mapDoSomething,它在list1中的每个元素和list2的每个元素上运行doSomething函数。

由于我使用了imap,列表在计算完成后立即打印出来,而不是等待整个结果完成。

最新更新