numpy数组索引意外行为

时间:2019-10-28 09:40:37

标签: python numpy

请考虑以下内容:

import numpy as np

X = np.ones((5,5))

print(X[:,0].shape)
print(X[:,0:1].shape)
  • X[:,0].shape返回(5,)

  • X[:,0:1].shape返回(5,1)

在两种情况下都选择了同一列(已建立索引),但是为什么会发生这种情况?背后的逻辑是什么?


X[:,-1:].shapeX[:,-1].shape

的情况完全相同

2 个答案:

答案 0 :(得分:1)

此行为可以通过以下事实来解释:与切片索引不同,使用说i的整数索引将返回与切片i:i+1相同的值,但返回的维数对象减少1docs中对此进行了解释:

  

特别是,第p个元素为整数(以及所有其他条目:)的选择元组将返回尺寸为N-1的相应子数组


我们可以编写一个简单的子类来仔细研究np.ndarray如何处理索引,并查看在每次调用中__getitem__ dunder会收到什么:

class ndarray_getitem_print(np.ndarray):
    def __getitem__(self, t):
        print(t)
        return super().__getitem__(t)

现在让我们实例化ndarray_getitem_print,看看用片和整数建立索引有什么区别:

a = ndarray_getitem_print((5,5))

a[:,0:1]

(slice(None, None, None), slice(0, 1, None))
(-5, -1)
(-4, -1)
(-3, -1)
(-2, -1)
(-1, -1)
ndarray_getitem_print([[1.],
                       [1.],
                       [1.],
                       [1.],
                       [1.]])

而使用0沿第二轴索引,将产生一个输出ndarray,其中每个项目都具有一维形状,即(-k,)

a[:,0]

(slice(None, None, None), 0)
(-5,)
(-4,)
(-3,)
(-2,)
(-1,)
ndarray_getitem_print([1., 1., 1., 1., 1.])

答案 1 :(得分:0)

我认为是因为索引?如果您打印两个函数的结果,则它们是不同的。在NxM np.array中,其数组为arrays。当用X [:,0]索引时,数组中的数组结构丢失。因此,shape只看到您得到的是单个数组而不是多维数组的内容。不带范围的AFAIK索引从列表/集合/内容中获取值。而按范围寻址时会切片。

访问类型时您会看到

>>> b = X[:,0]
>>> c = X[:,0:1]
>>> type(b)
<class 'numpy.ndarray'>
>>> type(c)
<class 'numpy.ndarray'>
>>> type(c[0])
<class 'numpy.ndarray'>
>>> type(b[0])
<class 'numpy.float64'>

仅显示两者之间的差异。

>>> c[0]
array([1.])
>>> b[0]
1.0