在二维数组的Vectorized移动的窗口在numpy

Ric*_*ich 10 python numpy vectorization

我在2D阵列上的恒定大小的移动窗口上应用操作.是否有一个有效的类似矢量化的操作,我可以实现这样做而无需在Python中循环?我目前的结构看起来像这样

 for i in range(1,xmax-1):
     for j in range(1,ymax-1):
        out[i][j] = f(in[i][j],in[i+1][j],in[i-1][j],in[i][j+1],in[i][j-1],...)
Run Code Online (Sandbox Code Playgroud)

这些评论可以留在这个问题暗指矢量化这种操作这种可能性,但没有进一步的细节矢量索引/切片在numpy的/ SciPy的?

mat*_*hat 7

如果你能表达这个功能

f(in[i][j],in[i+1][j],in[i-1][j],in[i][j+1],in[i][j-1],…)
Run Code Online (Sandbox Code Playgroud)

作为一个线性算,你可以使用SciPy的的signal.convolve2d函数来做到这一点.例如,假设您有一个50x50阵列,A,并且您想要计算第二个数组B,其中每个元素b[ij]都是a[i,j], a[(i-1),j], a[i,(j-1)], a[(i-1),(j-1)]数组A 的平均值.您可以这样做:

A = # your first array
B = numpy.ones((2,2))/4
C = scipy.signal.convolve2d(A,B, 'valid')
Run Code Online (Sandbox Code Playgroud)

当执行卷积时,阵列B在A上"滑动",将相应的元素相乘并对结果求和.由于边界效应,在使用结果数组C时必须小心.这里,由于'valid'参数在中convolve2d,C的形状为49x49,因为它们包含边界效果而丢弃第一行和第一行.如果你想拥有一个50x50阵列而不丢弃,你可以交换该参数'same'

编辑:也许如果你能告诉我更多关于你需要的功能,我可以更具体地帮助你把它变成一个用来进行2D卷积的数组.

希望有所帮助!


Foo*_*167 7

您可以使用滚动窗口技术作为解释在这里,这里这里,但对于二维数组.NumPy中2D滚动窗口的源代码:

# Rolling window for 2D arrays in NumPy
import numpy as np

def rolling_window(a, shape):  # rolling window for 2D array
    s = (a.shape[0] - shape[0] + 1,) + (a.shape[1] - shape[1] + 1,) + shape
    strides = a.strides + a.strides
    return np.lib.stride_tricks.as_strided(a, shape=s, strides=strides)

a = np.array([[0,  1,  2,  3,  4,  5],
              [6,  7,  8,  9, 10,  11],
              [12, 13, 14, 15, 7,   8],
              [18, 19, 20, 21, 13, 14],
              [24, 25, 26, 27, 19, 20],
              [30, 31, 32, 33, 34, 35]], dtype=np.int)
b = np.arange(36, dtype=np.float).reshape(6,6)
present = np.array([[7,8],[13,14],[19,20]], dtype=np.int)
absent  = np.array([[7,8],[42,14],[19,20]], dtype=np.int)

found = np.all(np.all(rolling_window(a, present.shape) == present, axis=2), axis=2)
print(np.transpose(found.nonzero()))
found = np.all(np.all(rolling_window(b, present.shape) == present, axis=2), axis=2)
print(np.transpose(found.nonzero()))
found = np.all(np.all(rolling_window(a, absent.shape) == absent, axis=2), axis=2)
print(np.transpose(found.nonzero()))
Run Code Online (Sandbox Code Playgroud)

数组在[1,1]和[2,4]上两次present出现在数组中a.