Numpy数组子集 - 意外行为

时间:2013-04-25 14:32:14

标签: python multidimensional-array numpy

我正在尝试复制一个numpy数组的子集(进行图像背景减法 - 但这是由by)。我不明白以下是什么问题 - 我已经以交互方式证明了这一点,因为你真的不想涉及我的所有代码......

>>> 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) - 并且在我需要用它做的后续操作中表现那样。我确信我已经做了一些非常明显错误的事情,但我无法解决问题。任何建议都感激不尽!

2 个答案:

答案 0 :(得分: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]相同,因为每个连续索引都会删除一个维度。但这并不适用于切片 - 你需要使用逗号。

答案 1 :(得分:3)

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

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

你正在做的事情是失败的,因为[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开始。第二个值比所需数组的索引大一个。这样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数组中获取切片已经创建了一个新对象。