为啥使用数组作为索引会改变多维 ndarray 的形状?

Posted

技术标签:

【中文标题】为啥使用数组作为索引会改变多维 ndarray 的形状?【英文标题】:Why using an array as an index changes the shape of a multidimensional ndarray?为什么使用数组作为索引会改变多维 ndarray 的形状? 【发布时间】:2019-09-13 17:25:26 【问题描述】:

我有一个 4-D NumPy 数组,轴为 x,y,z,t。我想取对应于 t=0 的切片并在 y 轴上排列顺序。

我有以下

import numpy as np
a = np.arange(120).reshape(4,5,3,2)
b = a[:,[1,2,3,4,0],:,0]
b.shape

我得到 (5, 4, 3) 而不是 (4,5,3)。

当我进入时

aa = a[:,:,:,0]
bb = aa[:,[1,2,3,4,0],:]
bb.shape

我得到了预期的 (4,5,3)。有人能解释一下为什么第一个版本会交换前两个维度吗?

【问题讨论】:

这是一个混合基本(切片)和高级索引的情况。它在主索引页面上进行了描述。切片尺寸放在最后。 @hpaulj 在第二个示例中,切片没有放在最后。能否解释一下原因或提供链接? 是中间的切片触发重新排序。该链接解释说,通过将切片尺寸放在后面可以解决潜在的歧义。我已经看到了这样的论点,即在一个索引是标量的情况下,这种歧义并不真正存在,但显然这很难彻底解决。幸运的是,您的两步索引绕过了这一点。它可能会更混乱,但不应该更慢。 【参考方案1】:

正如@hpaulj 在 cmets 中提到的,这种行为是由于混合了基本切片高级索引

a = np.arange(120).reshape(4,5,3,2)
b = a[:,[1,2,3,4,0],:,0]

在上面的代码sn-p中,发生的情况如下:

当我们沿最后一个维度进行基本切片时,它会触发__getitem__ 调用。所以,那个维度消失了。 (即没有单一维度)

[1,2,3,4,0] 从第二维返回 5 个切片。有两种可能将此形状放入返回的数组中:在第一个或最后一个位置。 NumPy 决定把它放在第一个维度。这就是为什么您在返回的形状元组的第一个位置得到 5 (5, ...) 的原因。如果我没记错的话,Jaime 在 PyCon 的一次演讲中解释了这一点。

沿第一和第三维度,由于您使用: 对所有内容进行切片,沿这些维度的原始长度将被保留。

将所有这些放在一起,NumPy 将形状元组返回为:(5, 4, 3)

您可以在numpy-indexing-ambiguity-in-3d-arrays 和arrays.indexing#combining-advanced-and-basic-indexing 了解更多信息

【讨论】:

您提供的第二个链接确实很有帮助。谢谢! 很高兴你发现它有用?

以上是关于为啥使用数组作为索引会改变多维 ndarray 的形状?的主要内容,如果未能解决你的问题,请参考以下文章

数据分析2 numpy(ndarray数组,属性,创建,索引切片,运算,函数,随机数), Pandas(Series创建,缺失值处理,特性,索引,DataFrame)

NumPy之:ndarray多维数组操作

用于多维 ndarray 的 argsort

NumPy数据分析基础:ndarray数组运算基本操作及切片索引迭代

ndarray对象的使用方法

科学计算和可视化