Numpy数组子集-意外行为



我试图复制numpy数组的一个子集(做图像背景减法-但那是顺便说一下)。我不明白下面的代码有什么问题——我用交互方式演示了它,因为你真的不想费力地浏览我所有的代码……

>>> from numpy import zeros
>>> a = zeros((5,5,3), 'uint8')
>>> print a.shape
(5, 5, 3)
>>> b = a[1:2][1:2][:].copy()
>>> print b.shape
(0, 5, 3)
>>> print a[1:2][1:2][:].shape
(0, 5, 3)
>>> print a.shape
(5, 5, 3)
>>>

我想要的是b.shape返回(2,2,3)-并且在我需要对它进行的后续操作中以这种方式表现。我肯定我做了什么很明显的错误,但我不知道是什么。任何建议,感谢收到!

我相信你指的是a[1:3, 1:3, :]而不是a[1:2][1:2][:]

同样,a[1:3, 1:3, ...]也可以工作(...意味着"尽可能多的:")。NumPy似乎也允许a[1:3, 1:3] .

有两部分的解释:

  1. 切片在Python中是左包容右排斥的

  2. 逗号索引在这里是必要的,a[1:3]给你一个形状(2,5,3)和另一个[1:3]将再次通过第一个维度切片。

    对于简单索引a[1][2][3]a[1,2,3]相同,因为每次连续索引删除一个维度。但是,这不适用于切片,您需要使用逗号。

你正在做的事情有两个不同的问题。最主要的是你如何在numpy中处理索引。Numpy矩阵有自己的语法,比你正在使用的列表的列表语法清晰得多……使用逗号代替括号中单独的索引:

>>> from numpy import zeros
>>> a = zeros((5,5,3), 'uint8')
>>> print a[1:2,1:2,:].shape
(1, 1, 3)

你所做的是失败的,因为a[1:2]仍然返回一个列表的列表,所以你的下一个索引是外部列表(只有一个元素)的索引,而不是你想要的内部列表:

>>> a[1:2]
array([[[0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0],
        [0, 0, 0]]], dtype=uint8)
>>> a[1:2][1:2]
array([], shape=(0, 5, 3), dtype=uint8)

(如果您使用简单的索引而不是切片,就不会有这个问题,但是您仍然应该使用逗号语法,因为它更清晰。

第二,你错误地使用了切片。切片的第一个值是您想要的数组的第一个值的索引——索引从0开始。第二个值比您想要的数组的索引大1。这是为了让a[first_index:second_index]返回second_index-first_index点。所以,你想要这样写:

>>> b = a[0:2,0:2,:]
>>> b
array([[[0, 0, 0],
        [0, 0, 0]],
       [[0, 0, 0],
        [0, 0, 0]]], dtype=uint8)

你的[1:2]索引将只返回一个元素…列表中的第二个

另外,作为旁注,.copy()在这里是多余的,因为从numpy数组中获取切片已经创建了一个新对象。

相关内容

  • 没有找到相关文章

最新更新