2016-08-03 249 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