簡體   English   中英

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

[英]Vectorizing nested for loops in list comprehension

我有兩個用於計算Damerau–Levenshtein距離的字符串列表,以檢查哪些相似。 我擁有的那些列表的問題超過200k +,並且具有理解力,這需要花費大量時間。 對於距離計算,我使用的是用Cython編寫的pyxDamerauLevenshtein包,因此應該沒有瓶頸

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

如果您可以想到一種使用地圖(或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,因此列表在計算后就立即打印出來,而不是等待整個結果完成。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM