我有一个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 。我知道,数组的大小比可用内存大。是否有优雅的方式或加快循环? 我不需要存储中间数组,我只对结果感兴趣。
谢谢!
答案 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)
但即使简化了,你也要创建两个大的临时数组。如果a
和b
的大小为M和N,则b - a
和abs(...)
分别创建一个大小为(M,N)的临时数组。因为你已经说过a
单调递增,所以你可以通过使用二进制搜索(排序搜索)来避免这个问题。看一下我前一段时间写给question的答案。使用此答案中的函数,试试这个:
closest = find_closest(array1[:, 0], array2[:, 0])
array2[:, 2] = array1[closest, 1]