Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在numpy中围绕二维阵列的边包裹切片_Python_Numpy - Fatal编程技术网

Python 在numpy中围绕二维阵列的边包裹切片

Python 在numpy中围绕二维阵列的边包裹切片,python,numpy,Python,Numpy,假设我在Python中使用numpy,我有一个任意大小的二维数组。为了方便起见,假设我有一个5 x 5的数组。具体数字对我的问题并不特别重要;他们只是一个例子 a = numpy.arrange(25).reshape(5,5) 这将产生: [[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]] 现在,假设我想对这个数组进行一个2D切片。在正常情况下,这很容易

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

a = numpy.arrange(25).reshape(5,5)
这将产生:

[[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]]
现在,假设我想对这个数组进行一个2D切片。在正常情况下,这很容易。为了得到紧靠2,2的单元格,我只需使用
a[1:4,1,4]
,这将产生预期的结果

[[6, 7,   8 ],
 [11, 12, 13],
 [16, 17, 18]]
但是如果我想吃一片能裹住你的肉呢 围绕阵列的边缘?例如,
a[-1:2,-1:2]
将产生:

[24, 20, 21],
[4, 0,  1 ],
[9, 5,  6 ] 
这在一些边缘无关紧要的情况下非常有用,例如环绕屏幕的游戏图形。我意识到这可以通过很多if语句和边界检查来实现,但我想知道是否有更干净、更惯用的方法来实现这一点

环顾四周,我发现了如下几种答案:适用于一维数组,但我还没有弄清楚如何将这种逻辑应用于二维切片

所以本质上,问题是:如何在numpy中获取二维数组的二维切片,该切片环绕数组的边缘


提前感谢所有能够提供帮助的人。

在尝试了一段时间各种方法之后,我找到了一个非常简单的解决方案,它可以使用
ndarray.take
。使用我在问题中提供的示例:

a.take(range(-1,2),mode='wrap', axis=0).take(range(-1,2),mode='wrap',axis=1)
提供所需的输出

[[24 20 21]
 [4  0   1]
 [9  5  6]]
结果比我想象的要简单得多。如果反转两个轴,此解决方案也有效

这与我以前使用
take
看到的答案类似,但我以前没有看到任何人解释如何将其用于2D数组,因此我发布这篇文章,希望它能帮助将来有同样问题的人。

您也可以使用,滚动数组,然后进行切片:

b = np.roll(np.roll(a, 1, axis=0), 1, axis=1)[:3,:3]
给予


正如我在评论中提到的,这是一个很好的答案

下面是另一个简单的方法

# First some setup
import numpy as np
A = np.arange(25).reshape((5, 5))
m, n = A.shape
然后

A[np.arange(i-1, i+2)%m].reshape((3, -1))[:,np.arange(j-1, j+2)%n]
要获得可以分配给你的东西有些困难。 这是一个稍微慢一点的版本。 为了得到类似的值切片,我必须

A.flat[np.array([np.arange(j-1,j+2)%n+a*n for a in xrange(i-1, i+2)]).ravel()].reshape((3,3))
为了分配给这一点,我必须避免调用重塑,并直接使用索引返回的扁平版本。 以下是一个例子:

n = 7
A = np.zeros((n, n))
for i in xrange(n-2, 0, -1):
    A.flat[np.array([np.arange(i-1,i+2)%n+a*n for a in xrange(i-1, i+2)]).ravel()] = i+1
print A
返回

[[ 2.  2.  2.  0.  0.  0.  0.]
 [ 2.  2.  2.  3.  0.  0.  0.]
 [ 2.  2.  2.  3.  4.  0.  0.]
 [ 0.  3.  3.  3.  4.  5.  0.]
 [ 0.  0.  4.  4.  4.  5.  6.]
 [ 0.  0.  0.  5.  5.  5.  6.]
 [ 0.  0.  0.  0.  6.  6.  6.]]

这将适用于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]])
pad例程有一个“换行”方法

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]])

根据不同的情况,您可能必须在任何切片的每个术语中添加1,以解释
b

周围的填充,我在使用环绕索引时遇到了类似的挑战,只是在我的情况下,我需要在原始矩阵中设置值。我通过“奇特的索引”和使用网格网格函数解决了这个问题:

A = arange(25).reshape((5,5)) # destinatoin matrix
print 'A:\n',A

k =-1* np.arange(9).reshape(3,3)# test kernel, all negative
print 'Kernel:\n', k
ix,iy = np.meshgrid(arange(3),arange(3)) # create x and y basis indices

pos = (0,-1) # insertion position

# create insertion indices
x = (ix+pos[0]) % A.shape[0]
y = (iy+pos[1]) % A.shape[1]
A[x,y] = k # set values
print 'Result:\n',A
输出:

A:
[[ 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]]
Kernel:
[[ 0 -1 -2]
 [-3 -4 -5]
 [-6 -7 -8]]
Result:
[[-3 -6  2  3  0]
 [-4 -7  7  8 -1]
 [-5 -8 12 13 -2]
 [15 16 17 18 19]
 [20 21 22 23 24]]

你为什么不先将数组展平,然后再重塑它的形状,然后使用
array.take(index,mode='wrap')
?看起来是这样的问题:虽然它看起来是一个副本,而不是一个视图…@IanH--是的,这似乎是我想要的。谢谢我在发帖前搜索时没有看到这一点。+1:对于你想要包装的卷积,这是一个很好的解决方案。谢谢,我不知道
pad
(当我需要它时,我已经手动完成了……不再需要了)。
A:
[[ 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]]
Kernel:
[[ 0 -1 -2]
 [-3 -4 -5]
 [-6 -7 -8]]
Result:
[[-3 -6  2  3  0]
 [-4 -7  7  8 -1]
 [-5 -8 12 13 -2]
 [15 16 17 18 19]
 [20 21 22 23 24]]