numpy 如何理解以下多维数组的奇特索引行为?

x8diyxa7  于 2023-06-23  发布在  其他
关注(0)|答案(2)|浏览(122)

我们注意到,花哨的索引和切片的混合使用对于多维数组来说是如此令人困惑和无记录,例如:

In [114]: x = np.arange(720).reshape((2,3,4,5,6))

In [115]: x[:,:,:,0,[0,1,2,4,5]].shape
Out[115]: (2, 3, 4, 5)

In [116]: x[:,:,0,:,[0,1,2,4,5]].shape
Out[116]: (5, 2, 3, 5)

我读过https://numpy.org/doc/stable/user/basics.indexing.html上的花式索引的用法,我可以理解x[:,0,:,[1,2]] = [x[:,0,:,1], x[:,0,:,2]]。然而,我不明白为什么上面Input [115]Input [116]的结果在第一维度上不同。有人能指出这样的广播规则是在哪里记录的吗?
谢谢!
我试着在文档中搜索花哨的索引,并将问题发布到Github上的numpy repo。

zpgglvta

zpgglvta1#

索引操作有两个部分,由基本索引定义的子空间(不包括整数)和来自高级索引部分的子空间。需要区分两种指标组合情况:

  • 高级索引由切片、省略号或新轴分隔。例如x[arr1,:,arr2]。
  • 高级索引都是紧挨着的。例如x[...,arr1,arr2,:],但不是x[arr1,:,1],因为在这方面1是高级索引。

在第一种情况下,由高级索引操作产生的维度首先出现在结果数组中,然后是子空间维度。在第二种情况下,来自高级索引操作的维度被插入到结果数组中与它们在初始数组中相同的位置(后一种逻辑使简单的高级索引表现得就像切片一样)。
来自https://numpy.org/doc/stable/user/basics.indexing.html#combining-advanced-and-basic-indexing
在你的第一个例子中,在第四和第五维度中有高级索引(高级索引是在两个维度中“彼此相邻”)。在第二个示例中,有一个切片操作(基本索引)将两个高级索引分开。

6yjfywim

6yjfywim2#

关于为什么会有歧义的一些额外见解:
在问题的后一种情况下,第3和第5轴被索引,因此从新数组中消失。必须在某处添加一个新的轴(形状与索引的广播相同)。如果我是numpy,并且必须将shape (5,)数组插入到具有“shape”(2, 3, -, 5, -)的数组中,我会将其放置在第一个缺失维度的位置吗?还是第二个?
正是因为一个切片分隔了两个高级索引,numpy不能替换一组连续的轴,因此不知道是在分隔切片之前还是之后插入新轴。因此,新轴将在前面插入:

(5, 2, 3, 5)
 ^  ^^^^^^^--- old dimensions
 |
new dimension

只有在第一种情况下,消失的轴都是相邻的(“形状”(2, 3, 4, -, -)),新的轴才能明确地插入到最后。
注意:在幕后,numpy总是在开始时插入新轴。它只是(我相信主要是为了方便)在不含糊的时候转置数组来移动新的轴。
同样有趣的是Numpy增强提案21

相关问题