Python Numpy数组索引意外行为

Python Numpy数组索引意外行为,python,numpy,Python,Numpy,考虑以下几点: import numpy as np X = np.ones((5,5)) print(X[:,0].shape) print(X[:,0:1].shape) X[:,0]。形状返回(5,) X[:,0:1]。形状返回(5,1) 在这两种情况下,都会选择相同的列(索引),但为什么会发生这种情况?背后的逻辑是什么 与X[:,-1:]完全相同。shape和X[:,-1]。shape这一行为的解释是,与使用切片索引不同,使用sayi进行整数索引,将返回与切片i:i+1相同的

考虑以下几点:

import numpy as np

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

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

  • X[:,0:1]。形状
    返回
    (5,1)

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



X[:,-1:]完全相同。shape
X[:,-1]。shape

这一行为的解释是,与使用切片索引不同,使用say
i
进行整数索引,将返回与切片
i:i+1
相同的值,但返回对象的维数将减少
1
。下文对此进行了解释:

特别是,第p个元素为整数(以及所有其他项:)的选择元组返回维度为N-1的对应子数组


我们可以编写一个简单的子类来更仔细地了解
np.ndarray
如何处理索引,并查看
\uuu getitem\uuuu
dunder在每个调用中接收到什么:

class ndarray_getitem_print(np.ndarray):
    def __getitem__(self, t):
        print(t)
        return super().__getitem__(t)
现在让我们实例化
ndarray\u getitem\u 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
进行索引将产生一个输出数据阵列,其中每个项目都具有一维形状,即
(-k,)


我想是因为索引?如果打印两个函数的结果,则它们是不同的。在NxM np.array中,其数组在数组中。使用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'>
>>> 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