用numpy中的广播替换循环 - >记忆错误

时间:2014-07-11 18:45:49

标签: python loops numpy

我有一个2D数组(array1),它有任意数量的行,在第一列中我有严格单调递增的数字(但不是线性),它代表我系统中的一个位置,而第二个给出一个值,表示我的系统在第一列中的位置和周围的状态。

现在我有了第二个数组(array2);它的范围通常应与第一个数组的第一列相同,但无关紧要,如下所示。 我现在对array2中的每个元素感兴趣: 1. array1 [:,0]中的参数是什么,它与array2中的当前元素具有最接近的值? 2.这些元素的值(array1 [:,1])是多少。

因为通常array2会比array1中的行数长,所以如果我从array1中得到一个参数多次,那就非常好了。实际上这就是我的期望。 2.的值写在第二和第三列,如下所示。

我的条纹代码如下所示:

from numpy import arange, zeros, absolute, argmin, mod, newaxis, ones


ysize1 = 50
array1 = zeros((ysize1+1,2))


array1[:,0]   = arange(ysize1+1)**2      
    # can be any strictly monotonic increasing array 
array1[:,1]   = mod(arange(ysize1+1),2)  
    # in my current case, but could also be something else



ysize2      = (ysize1)**2
array2      = zeros((ysize2+1,3))
array2[:,0]   = arange(0,ysize2+1)                  
# is currently uniformly distributed over the whole range, but does not necessarily have to be


a = 0
for i, array2element in enumerate(array2[:,0]):
    a = argmin(absolute(array1[:,0]-array2element))
    array2[i,1] = array1[a,1]

它可以工作,但需要花费大量时间来处理大型数组。然后我尝试实现广播,这似乎与以下代码一起使用:

indexarray = argmin(absolute(ones(array2[:,0].shape[0])[:,newaxis]*array1[:,0]-array2[:,0][:,newaxis]),1)
array2[:,2]=array1[indexarray,1]    # just to compare the results

不幸的是现在我似乎遇到了一个不同的问题:我在广播代码行中使用的数组大小出现内存错误。 对于小尺寸它可以工作,但对于较大的尺寸,len(array2 [:,0])类似于2 ** 17(可能更大)和len(array1 [:,0])大约是2 ** 14 。我知道,数组的大小比可用内存大。是否有优雅的方式或加快循环? 我不需要存储中间数组,我只对结果感兴趣。

谢谢!

1 个答案:

答案 0 :(得分:0)

首先让我们简化这一行:

argmin(absolute(ones(array2[:,0].shape[0])[:,newaxis]*array1[:,0]-array2[:,0][:,newaxis]),1)

它应该是:

a = array1[:, 0]
b = array2[:, 0]
argmin(abs(a - b[:, newaxis]), 1)

但即使简化了,你也要创建两个大的临时数组。如果ab的大小为M和N,则b - aabs(...)分别创建一个大小为(M,N)的临时数组。因为你已经说过a单调递增,所以你可以通过使用二进制搜索(排序搜索)来避免这个问题。看一下我前一段时间写给question的答案。使用此答案中的函数,试试这个:

closest = find_closest(array1[:, 0], array2[:, 0])
array2[:, 2] = array1[closest, 1]