在numpy中围绕2D数组的边缘包裹切片

Geo*_*eil 9 python numpy

假设我在Python中使用numpy并且我有一个任意大小的二维数组.为方便起见,假设我有一个5 x 5阵列.具体数字对我的问题不是特别重要; 他们只是一个例子.

a = numpy.arrange(25).reshape(5,5)
Run Code Online (Sandbox Code Playgroud)

这会产生:

[[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]]
Run Code Online (Sandbox Code Playgroud)

现在,假设我想拍摄这个数组的2D切片.在正常情况下,这很容易.为了让细胞紧邻2,2,我只需使用a[1:4,1,4]哪种产生预期的效果

[[6, 7,   8 ],
 [11, 12, 13],
 [16, 17, 18]]
Run Code Online (Sandbox Code Playgroud)

但是,如果我想采取一个包裹阵列边缘的切片呢?例如a[-1:2,-1:2]会产生:

[24, 20, 21],
[4, 0,  1 ],
[9, 5,  6 ] 
Run Code Online (Sandbox Code Playgroud)

这在边缘无关紧要的几种情况下是有用的,例如围绕屏幕的游戏图形.我意识到这可以通过很多if语句和边界检查来完成,但我想知道是否有更简洁,更惯用的方法来实现这一点.

环顾四周,我找到了几个答案:https://stackoverflow.com/questions/17739543/wrapping-around-slices-in-python-numpy适用于一维数组,但我还没弄清楚如何将此逻辑应用于2D切片.

基本上,问题是:如何在numpy中包围数组边缘的2D数组?

提前感谢任何可以提供帮助的人.

Tim*_*era 13

这将适用于numpy> = 1.7.

a = np.arange(25).reshape(5,5)

array([[ 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]])
Run Code Online (Sandbox Code Playgroud)

pad例程有一个'wrap'方法......

b = np.pad(a, 1, mode='wrap')

array([[24, 20, 21, 22, 23, 24, 20],
       [ 4,  0,  1,  2,  3,  4,  0],
       [ 9,  5,  6,  7,  8,  9,  5],
       [14, 10, 11, 12, 13, 14, 10],
       [19, 15, 16, 17, 18, 19, 15],
       [24, 20, 21, 22, 23, 24, 20],
       [ 4,  0,  1,  2,  3,  4,  0]])
Run Code Online (Sandbox Code Playgroud)

根据具体情况,您可能需要为任何切片的每个术语添加1,以便考虑周围的填充b.


Geo*_*eil 10

在使用各种方法一段时间之后,我只是找到了一个可以使用的相当简单的解决方案ndarray.take.使用我在问题中提供的示例:

a.take(range(-1,2),mode='wrap', axis=0).take(range(-1,2),mode='wrap',axis=1)
Run Code Online (Sandbox Code Playgroud)

提供所需的输出

[[24 20 21]
 [4  0   1]
 [9  5  6]]
Run Code Online (Sandbox Code Playgroud)

事实证明它比我想象的要简单得多.如果您反转两个轴,此解决方案也适用.

这类似于我以前看过的答案take,但是我没有看到有人解释它之前是如何与2D数组一起使用的,所以我发布这个希望它可以帮助有相同问题的人未来.