2016-08-03 491 views
5

我正在尋找向量化嵌套循環,這將工作在300,000列表的列表上,每個列表包含3個值。嵌套循環將每個列表的值與其他列表中的對應值進行比較,並且將僅添加具有它們之間具有最大差值0.1的對應值的列表索引。因此,含有[0.234,0.456,0.567]的清單和含有[0.246,0.479,0.580]的清單屬於這一類別,因爲它們的相應數值(即0.234和0.246; 0.456和0.479; 0.567和0.580)有差異它們之間小於0.1。向量化嵌套循環

我目前使用下面的嵌套循環來做到這一點,但它目前需要約58小時才能完成(總共90萬億次迭代);

import numpy as np 
variable = np.random.random((300000,3)).tolist() 
out1=list() 
out2=list() 
for i in range(0:300000): 
    for j in range(0:300000): 
     if ((i<j) and ((abs(variable[i][0]-variable[j][0]))<0.1) and ((abs(variable[i][1]-variable[j] [1]))<0.1) and ((abs(variable[i][2]-variable[j][2]))<0.1)): 
     out1.append(i) 
     out2.append(j) 
+0

你'variable'是隨機的,它只是爲例子,或者是你真正模擬的東西嗎? – Julien

+0

是的,它只是爲了舉例 - 實際上我有一個列表,通過模擬生成,實際上有數據落在我提到的閾值內。 – JBorg

回答

3

看看scipy.spatial;它有很多功能可以高效地解決這些空間查詢問題; KDTrees特別,即:

import scipy.spatial 
out = scipy.spatial.cKDTree(variable).query_pairs(r=0.1, p=np.infinity) 
+0

試過這個;它返回「需要浮動」。我認爲這很簡單,感謝您的回覆! – JBorg

+0

啊我誤解了文檔;他們在這個問題上特別清楚。嘗試編輯。 「無限規範」應歸結爲您正在尋找的指標;任何組件的最大絕對值。 –

+0

請注意,爲了提高效率,最好放棄完全贊成ndarrays的列表。這適用於您的輸入,也適用於輸出;請注意,您可以將output_type ='ndarray'kwarg添加到此調用中。 –

3

轉換爲NumPy數組,以便後續使用NumPy函數。然後,可以建議兩種方法。

方法#1

NumPy的廣播可被用於擴展這些到3D陣列和在向量化的方式執行操作。因此,我們必須像這樣的實現 -

th = 0.1 # Threshold 
arr = np.asarray(variable) 
out1,out2 = np.where(np.triu((np.abs(arr[:,None,:] - arr) < th).all(-1),1)) 

方法2

,重點是內存使用效率的替代實現,它使用選擇性指數將負責這種迭代 -

th = 0.1 # Threshold 
arr = np.asarray(variable) 
R,C = np.triu_indices(arr.shape[0],1) 
mask = (np.abs(arr[R] - arr[C])<th).all(-1) 
out1,out2 = R[mask], C[mask] 
+0

這將工作,如果你有一個TB的RAM,是的:) –

+0

@EelcoHoogendoorn'方法#2'可能不那麼重:) – Divakar

+0

試過這個,但越來越內存錯誤;只用了30,000個列表再試了一遍,仍在運行;我猜這還需要很長時間?在256Gb RAM上運行 – JBorg