我如何从一个较大的2D numpy数组中提取一组2D切片?



如果我有一个大的2D numpy数组和两个对应于我想要提取的x和y下标的数组,这很容易:

h = np.arange(49).reshape(7,7)
# h = [[0, 1, 2, 3, 4, 5, 6],
#      [7, 8, 9, 10, 11, 12, 13],
#      [14, 15, 16, 17, 18, 19, 20],
#      [21, 22, 23, 24, 25, 26, 27],
#      [28, 29, 30, 31, 32, 33, 34],
#      [35, 36, 37, 38, 39, 40, 41],
#      [42, 43, 44, 45, 46, 47, 48]]
x_indices = np.array([1,3,4])
y_indices = np.array([2,3,5])
reduced_h = h[x_indices, y_indices]
#reduced_h = [ 9, 24, 33]

然而,我想为每个x,y对切割出一个正方形(用'a'表示-从中心开始的每个方向的索引数)围绕这个"坐标",并返回这些小的二维数组的数组。

例如,对于上面的h, x,y_indices,并且a=1:

reduced_h = [[[1,2,3],[8,9,10],[15,16,17]], [[16,17,18],[23,24,25],[30,31,32]], [[25,26,27],[32,33,34],[39,40,41]]]

。E为每个x-y索引对对应于以x-y索引为中心的元素的3x3平方的3x3数组。通常,这应该返回一个numpy数组,其形状为(len(x_indices),2a+1, 2a+1)

通过类比reduced_h[0] = h[x_indices[0]-1:x_indices[0]+1 , y_indices[0]-1:y_indices[0]+1] = h[1-1:1+1 , 2-1:2+1] = h[0:2, 1:3],我的第一次尝试如下:

h[x_indices-a : x_indices+a, y_indices-a : y_indices+a]

然而,也许并不奇怪,数组之间的切片失败了。因此,接下来要尝试的显然是手动创建这个切片。np。range似乎与此斗争,但linspace工作:

a=1
xrange = np.linspace(x_indices-a, x_indices+a, 2*a+1, dtype=int)
# xrange = [ [0, 2, 3], [1, 3, 4], [2, 4, 5] ]
yrange = np.linspace(y_indices-a, y_indices+a, 2*a+1, dtype=int)

现在可以尝试h[xrange,yrange],但这并不奇怪,这个元素明智的意思是我只得到一个(2a+1)x(2a+1)数组(与xrange和yrange相同的维度)。是否有一种方法,对于每个索引,从这些范围中取出正确的切片(没有循环)?或者是否有一种方法可以使广播工作,而不必明确设置linspace ?由于

您可以使用x和y索引索引np.lib.stride_tricks.sliding_window_view:

import numpy as np
h = np.arange(49).reshape(7,7)
x_indices = np.array([1,3,4])
y_indices = np.array([2,3,5])
a = 1
window = (2*a+1, 2*a+1)
out = np.lib.stride_tricks.sliding_window_view(h, window)[x_indices-a, y_indices-a]

:

array([[[ 1,  2,  3],
[ 8,  9, 10],
[15, 16, 17]],
[[16, 17, 18],
[23, 24, 25],
[30, 31, 32]],
[[25, 26, 27],
[32, 33, 34],
[39, 40, 41]]])

请注意,您可能需要先填充h来处理到达"外部"的坐标周围的窗口。h.

最新更新