通过索引列表从numpy数组中切片子数组

时间:2014-11-05 09:12:34

标签: python arrays numpy slice

我有一个2D numpy数组input_array和两个索引列表(x_coordsy_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中工作

2 个答案:

答案 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()

绘制的图表

enter image description here

答案 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不在矩阵的边界。