Python 为什么Numpy中的数组索引会产生这种结果?

Python 为什么Numpy中的数组索引会产生这种结果?,python,numpy,Python,Numpy,根据,将数组索引指定为array\u name[x,y]和array\u name[x][y]是等效的,应该会产生相同的结果。但是,以下代码段: import numpy as np a = np.empty((7, 8, 9), dtype = object) # First indexing notation print(a[:, 0, 0].shape, a[0, :, 0].shape, a[0, 0, :].shape) # Second indexing notation prin

根据,将数组索引指定为
array\u name[x,y]
array\u name[x][y]
是等效的,应该会产生相同的结果。但是,以下代码段:

import numpy as np

a = np.empty((7, 8, 9), dtype = object)
# First indexing notation
print(a[:, 0, 0].shape, a[0, :, 0].shape, a[0, 0, :].shape)
# Second indexing notation
print(a[:][0][0].shape, a[0][:][0].shape, a[0][0][:].shape)
产生输出:

(7,) (8,) (9,)    
(9,) (9,) (9,)

这显然是不等价的。给出了什么?

您误解了numpy如何解释索引/切片。类似于
a[x,y,z]
,numpy使用
x
沿第一维度选择,沿第二维度选择
y
,沿第三维度选择
z

然而,对于像
a[x][y][z]
这样的东西,numpy沿着
a
的第一维度使用
x
,沿着
a[x][y]的第一维度使用
y
,沿着
a[x][y]的第一维度使用
z

如果将使用
与使用某个数字进行比较,这可能会令人困惑。为什么会这样?一个是切片(
),另一个是索引(no
)。因为沿维度切片(使用
)实际上并不会减少数组的维度,而索引确实会减少数组的维度

可能会有很多例子来说明这一点,但我认为最好让您在ipython中使用一个数组,看看不同的索引和切片如何影响输出。但是,我将提供一两个例子来专门回答您的问题

import numpy as np

a = np.arange(2*3*4).reshape((2,3,4))

a
array([[[ 0,  1,  2,  3],
        [ 4,  5,  6,  7],
        [ 8,  9, 10, 11]],

       [[12, 13, 14, 15],
        [16, 17, 18, 19],
        [20, 21, 22, 23]]])

# First indexing notation
print(a[:, 0, 0].shape, a[0, :, 0].shape, a[0, 0, :].shape)
# Prints (2,) (3,), (4,)
将其分解,我们将每个:

  • a[:,0,0]
    获取所有第一维度,而
    0
    th元素则获取第二维度和第三维度
  • a[0,:,0]
    获取第一维度的
    0
    th元素、第二维度的所有元素以及第三维度的
    0
    th元素
  • a[0,0,:]
    0
    th元素用于第一维度和第二维度,将所有元素用于第三维度

在这种情况下:

  • a[:]
    基本上与
    a
    相同(返回矩阵的新
    视图
    ——谷歌“numpy视图”获取更多信息)。由于
    a[:]
    a
    相同,
    a[:][0]
    选择
    0
    沿
    a
    第一维度的元素
  • 等等

OP说:

根据,将数组索引指定为array_name[x,y]和array_name[x][y]是等效的


这是真的!要认识到的主要一点是(尽管相关)索引和切片不是一回事(正如我上面指出的)。

使用
[:]
进行索引没有任何作用。即使有一个列表,它也只是复制。使用
x[…][…][…]
时,您必须单独查看每个索引操作的操作。口译员一次应用一个。在
[,…,…,…]
numpy
中,它们可以一起使用。等效性仅适用于单元素索引,而不适用于切片(使用
)或高级索引。明白了,谢谢。您还可以解释一下是什么导致Python在第二行生成结果吗?如果您省略了
[:]
,它可以归结为
a[0][0]
,这与
a[0,0]
a[0,0,:]
相同。但是第二行的所有三个表达式的计算结果都是[0,0,:]难道不奇怪吗?这是我遗漏的某种特征吗?这是有道理的。非常感谢。
# Second indexing notation
print(a[:][0][0].shape, a[0][:][0].shape, a[0][0][:].shape)
# Prints (4,) (4,) (4,)