NumPy数组索引的意外行为

3

请考虑以下内容:

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个回答

1
这种行为是由以下事实解释的:与使用切片索引不同,使用整数索引(例如i)将返回与切片i:i+1相同的值,但返回对象的维度减少了1。这在文档中有解释:

特别地,选择元组的第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.])

0

我认为这是由于索引的原因?如果打印两个函数的结果,它们是不同的。在一个NxM np.array中,它是数组中的数组。当您使用X [:,0]进行索引时,数组中数组的结构会丢失。因此,形状只看到您得到的单个数组,而不是多维数组。据我所知,没有范围的索引从列表/集合/某些东西中获取值。而当您通过范围寻址时,则进行切片。

当您访问类型时,可以看到这一点

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接