我有一个 2D numpy 数组 input_array
和两个索引列表(x_coords
和 y_coords
)。我想为每个 x,y 对以 x,y 坐标为中心切片 3x3 子数组。最终结果将是一个 3x3 子数组的数组,其中子数组的数量等于我拥有的坐标对的数量。
最好避免 for 循环。目前我使用 scipy 食谱中的生命游戏大步修改版: http://wiki.scipy.org/Cookbook/GameOfLifeStrides
shape = (input_array.shape[0] - 2, input_array.shape[0] - 2, 3, 3)
strides = input_array.strides + input_array.strides
strided = np.lib.stride_trics.as_strided(input_array, shape=shape, strides=strides).\
reshape(shape[0]*shape[1], shape[2], shape[3])
这将原始数组的 View 创建为所有可能的 3x3 子数组的(展平)数组。然后,我转换 x,y 坐标对,以便能够从 strided
中选择我想要的子数组:
coords = x_coords - 1 + (y_coords - 1)*shape[1]
sub_arrays = strided[coords]
虽然这工作得很好,但我确实觉得有点麻烦。有没有更直接的方法来做到这一点?另外,将来我想将其扩展到 3D 案例;从 nxmxk 数组中切片 nx3x3 子数组。使用跨步也可能是可行的,但到目前为止我还无法使其在 3D 中工作
最佳答案
这是一个使用数组广播的方法:
x = np.random.randint(1, 63, 10)
y = np.random.randint(1, 63, 10)
dy, dx = [grid.astype(int) for grid in np.mgrid[-1:1:3j, -1:1:3j]]
Y = dy[None, :, :] + y[:, None, None]
X = dx[None, :, :] + x[:, None, None]
然后你可以使用a[Y, X]
从a
中选择 block 。下面是一个示例代码:
img = np.zeros((64, 64))
img[Y, X] = 1
这是由 pyplot.imshow()
绘制的图表:
关于python - 按索引列表从 numpy 数组中切片子数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26753268/