Python numpy数组中的索引混淆

Python numpy数组中的索引混淆,python,arrays,numpy,Python,Arrays,Numpy,我真的被多维numpy数组的索引逻辑弄糊涂了。以下是一个例子: import numpy as np A = np.arange(18).reshape(3,2,3) [[[ 0, 1, 2], [ 3, 4, 5]], [[ 6, 7, 8], [ 9, 10, 11]], [[12, 13, 14], [15, 16, 17]]]) 这给了我一个形状数组(3,2,3),为了便于论证,将它们称为(x,y,z)。现在我想要一个数组B,其中A中的元素对应于x=0,

我真的被多维numpy数组的索引逻辑弄糊涂了。以下是一个例子:

import numpy as np
A = np.arange(18).reshape(3,2,3)
[[[ 0,  1,  2],
  [ 3,  4,  5]],

 [[ 6,  7,  8],
  [ 9, 10, 11]],

 [[12, 13, 14],
  [15, 16, 17]]])
这给了我一个形状数组(3,2,3),为了便于论证,将它们称为(x,y,z)。现在我想要一个数组B,其中A中的元素对应于x=0,2Y=0,1和z=1,2。像

array([[[ 1,  2],
        [4,  5]],

       [[13, 14],
        [16, 17]]])
我天真地认为

B=A[[0,2],[0,1],[1,2]]
我会做的。但它给

array([  2, 104]) 
而且不起作用

A[[0,2],:,:][:,:,[1,2]]

他做这项工作。但我仍然想知道我的第一次尝试有什么问题。做我想做的事情的最佳方法是什么?

我推荐以下高级教程,其中解释了各种索引方法:

一旦您了解了索引数组的强大方法(以及如何组合它们),这将是有意义的。如果您的第一次尝试是有效的,那么这将与其他一些索引技术发生冲突(减少您在其他用例中的选项)

在您的示例中,您可以利用第三个索引覆盖的连续范围:

 A[[0,2],:,1:]
你也可以使用

A[np.ix_([0,2],[0,1],[1,2])]
在更一般的情况下,当后一个指数不是连续的时,这是很方便的
np.ix
仅构造三个索引数组

正如斯文在回答中指出的那样,在这种特定情况下有一种更有效的方法(使用视图而不是复制的版本)


编辑:正如斯文指出的那样,我的回答中包含一些错误,我已经删除了这些错误。我仍然认为他的答案更好,但不幸的是,我现在不能删除我的答案。

在NumPy和中有两种类型的索引。基本索引使用切片元组进行索引,不复制数组,而是复制。相比之下,高级索引还使用索引列表或数组并复制数组

你的第一次尝试

B = A[[0, 2], [0, 1], [1, 2]]
使用高级索引。在高级索引中,所有索引列表首先指向同一形状,该形状用于输出数组。在这种情况下,它们已经具有相同的形状,因此广播不起任何作用。输出数组也将具有两个条目的这种形状。输出数组的第一个条目通过使用三个列表的所有第一个索引获得,第二个条目通过使用所有第二个索引获得:

B = numpy.array([A[0, 0, 1], A[2, 1, 2]])
你的第二种方法

B = A[[0,2],:,:][:,:,[1,2]]
确实有效,但效率很低。它使用高级索引两次,因此您的数据将被复制两次

要使用高级索引获得实际需要的内容,可以使用

A[np.ix_([0,2],[0,1],[1,2])]
正如他所指出的那样。这将只复制一次数据

在您的示例中,您可以不复制任何数据,只使用基本索引:

B = A[::2, :, 1:2]
如果你愿意

array([[[ 1,  2],
        [ 4,  5]],

       [[13, 14],
        [16, 17]]])

A[需要索引,需要行,需要列]

一些备注:1。前两个代码段是不等价的——它们产生不同形状的数组。第一行的解释与第二行不同。2.jonalm的解决方案不可取,因为它会复制阵列两次。我试着在另一个答案中解释这些问题。谢谢Sven,但是有没有比使用高级索引更好的方法从数组中提取非连续(或规则间隔)的索引。(我的例子太简单了,因为我提取的所有索引都是连续间隔的)如果您的索引不是规则间隔的,您当然必须使用高级索引。正如nikow已经指出的那样,本例中的方法是使用
ix_u
语法。我只是想补充一些细节,比如你自己的方法对于大型阵列效率低下。回答得很好,谢谢你指出我的错误。我应该考虑一下高级索引对效率的影响。我个人的看法是:你的两种方法都会触发Numpy的高级索引。在高级索引上下文中,[[0,2]、[0,1]、[1,2]]被解释为“选择每个维度中的每个索引编号(有点贪婪的方法)。
array([[[ 1,  2],
        [ 4,  5]],

       [[13, 14],
        [16, 17]]])