我有一个2D numpy数组input_array
和两个索引列表(x_coords
和y_coords
)。我想为每个围绕x,y坐标的x,y对切片3x3子阵列。最终结果将是3x3子阵列的数组,其中子阵列的数量等于我具有的坐标对的数量。
最好避免循环。目前我使用scipy cookbook改变生活游戏的步伐: 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])
这将创建原始数组的视图,作为所有可能的3x3子阵列的(展平)数组。然后我转换x,y坐标对,以便能够从strided
中选择我想要的子阵列:
coords = x_coords - 1 + (y_coords - 1)*shape[1]
sub_arrays = strided[coords]
虽然这种方法非常好,但我觉得它有点麻烦。有没有更直接的方法来做到这一点?此外,将来我想将其扩展到3D案例;从nxmxk数组中切割nx3x3子数组。也许有可能使用步幅,但到目前为止我还没能使它在3D中工作
答案 0 :(得分:3)
这是一个使用数组广播的方法:
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
中选择块。这是一个示例代码:
img = np.zeros((64, 64))
img[Y, X] = 1
以下是pyplot.imshow()
:
答案 1 :(得分:0)
一个非常直接的解决方案是列表理解和itertools.product
:
import itertools
sub_arrays = [input_array[x-1:x+2, y-1:y+2]
for x, y in itertools.product(x_coords, y_coords)]
这会创建所有可能的坐标元组,然后从input_array
切片3x3数组。
但这是一个for循环。而且你必须小心,x_coords和y_coords不在矩阵的边界。