迭代多维Numpy数组

时间:2015-10-28 21:54:44

标签: numpy multidimensional-array indexing

迭代3D NumPy数组中所有元素的最快方法是什么?如果array.shape = (r,c,z),必须有比这更快的东西:

x = np.asarray(range(12)).reshape((1,4,3))

#function that sums nearest neighbor values
x = np.asarray(range(12)).reshape((1, 4,3))

#e is my element location, d is the distance
def nn(arr, e, d=1):
    d = e[0]
    r = e[1]
    c = e[2]
    return sum(arr[d,r-1,c-1:c+2]) + sum(arr[d,r+1, c-1:c+2]) + sum(arr[d,r,c-1]) + sum(arr[d,r,c+1]) 

而不是像下面那样创建嵌套的for循环来创建我的e值,以便为每个像素运行函数nn

for dim in range(z):
    for row in range(r):
        for col in range(c):
            e = (dim, row, col)  

我希望以提取每个元素(例如nn)的位置信息的方式向量化e = (0,1,1)函数,并迭代矩阵中的所有元素而无需手动输入每个位置值e或者创建一个混乱的嵌套for循环。我不确定如何将np.vectorize应用于此问题。谢谢!

2 个答案:

答案 0 :(得分:1)

很容易在d维度上进行矢量化:

def nn(arr, e):
        r,c = e  # (e[0],e[1])
        return np.sum(arr[:,r-1,c-1:c+2],axis=2) + np.sum(arr[:,r+1,c-1:c+2],axis=2) + 
            np.sum(arr[:,r,c-1],axis=?) + np.sum(arr[:,r,c+1],axis=?)

现在只迭代row和col维度,返回一个向量,该向量分配给x中的相应插槽。

for row in <correct range>:
    for col in <correct range>:
        x[:,row,col] = nn(data, (row,col))

下一步是制作

rows = [:,None]    cols =    arr [:,rows-1,cols + 2] + arr [:, rows,cols + 2]等。

这种问题多次出现,有各种描述 - 卷积,平滑,过滤等。

我们可以进行一些搜索以找到最佳效果,或者您更喜欢,我们可以指导您完成这些步骤。

Converting a nested loop calculation to Numpy for speedup

是一个类似于你的问题。只有2级循环,sum表达式不同,但我认为它有同样的问题:

for h in xrange(1, height-1):
   for w in xrange(1, width-1):
      new_gr[h][w] = gr[h][w] + gr[h][w-1] + gr[h-1][w] +
               t * gr[h+1][w-1]-2 * (gr[h][w-1] + t * gr[h-1][w])

答案 1 :(得分:0)

这就是我最终做的事情。由于我正在返回xv向量并将其滑入更大的3D数组lag,这应该可以加快进程,对吧? data是我的输入数据集。

def nn3d(arr, e):
    r,c = e

    n = np.copy(arr[:,r-1:r+2,c-1:c+2])
    n[:,1,1] = 0

    n3d = np.ma.masked_where(n == nodata, n)

    xv = np.zeros(arr.shape[0])
    for d in range(arr.shape[0]):
        if np.ma.count(n3d[d,:,:]) < 2:
            element = nodata
        else:
            element = np.sum(n3d[d,:,:])/(np.ma.count(n3d[d,:,:])-1)
        xv[d] = element

    return xv

lag = np.zeros(shape = data.shape)        
for r in range(1,data.shape[1]-1): #boundary effects
    for c in range(1,data.shape[2]-1):
        lag[:,r,c] = nn3d(data,(r,c))