矢量化嵌套循环

时间:2016-08-03 14:12:51

标签: python numpy vectorization

我希望对一个嵌套循环进行矢量化,这将在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)

2 个答案:

答案 0 :(得分: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]

答案 1 :(得分:3)

看看scipy.spatial;它有很多功能可以有效地解决这些空间查询;特别是KDTrees,即:

import scipy.spatial
out = scipy.spatial.cKDTree(variable).query_pairs(r=0.1, p=np.infinity)
相关问题