Python数组使用列表作为索引,但是数组的维度被置换了。

5

我尝试使用列表来索引一个五维数组。然而,在某些情况下,该数组会被置换。

比如,a的形状为(3,4,5,6,7),即

>>> a = np.zeros((3,4,5,6,7))
>>> a.shape
(3, 4, 5, 6, 7)

使用列表在第三维度上进行索引,看起来很正常:

>>> a[:,:,[0,3],:,:].shape
(3, 4, 2, 6, 7)

然而,如果在以下情况下对数组进行索引,则第三维会被置于最左侧:

>>> a[0,:,[0,1],:,:].shape
(2, 4, 6, 7)

有人能解释一下吗?
2个回答

1

基本切片:-

当使用slice对象时,会发生基本切片。通常,切片对象构造为array[(start:stop:step)]。省略号和newaxis也属于此类。

例子:1D数组

>>x=np.arange(10)    
>>x[2:10:3]
 array([2, 5, 8])

例子:2D数组

>>>x = np.array([[1,2,3], [4,5,6]])
>>>x[1:2]
array([[4, 5, 6]])

示例:- 3D数组

>>>x = np.array([[[1],[2],[3]], [[4],[5],[6]]])
>>> x[0:1]
array([[[1],
        [2],
        [3]]])

在上面的例子中,给定的切片数量(obj)小于数组的总维数。如果选择元组中的对象数量小于N,则假定为任何后续维度。
高级切片:-
当选择对象obj是非元组序列对象、ndarray(数据类型为整数或布尔值)、至少一个序列对象或ndarray(数据类型为整数或布尔值)时,将触发高级索引。
有两种高级索引:整数和布尔。
整数索引:-
整数数组索引允许基于它们的N维索引选择数组中的任意项。每个整数数组表示该维度中的索引数。
当索引由与被索引数组具有相同维度的整数数组组成时,索引是直接的,但与切片不同。
例如:
>>a = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>a[[0,1,2],[0,1,1]]
array([1, 5, 8])

Array Visualization

上面的示例输出: a[0,0],a[1,0],a[2,1] 记住:整数索引映射在两个索引之间。
现在回答你的问题:
>>>a=np.array([3,4,5])
>>>a[0,:,[0,1]]

第一种情况:-

这是形式为x[arr1,:,arr2]的格式。 arr1和arr2是高级索引。我们认为0也是高级索引。

如果高级索引由切片、省略号或新轴分隔,则高级索引操作产生的维度首先出现在结果数组中,然后是子空间维度。

这意味着[0,1]的维度首先出现在数组中。我将0省略,因为它没有维度。

>>>a[0,:,[0,1]].shape
(2,4)

第二种情况:

这种形式为x[:,:,arr1]。这里只有arr1是高级索引。

如果所有高级索引都相邻,则从高级索引操作中的维度将插入到结果数组中与它们在初始数组中的位置相同的位置。

这意味着[0,1]的维度将在其在数组索引中指定的相应位置处出现。

>>>a[0:1,:,[0,1]].shape
(1,4,2)

[0,1] 的形状为 (2,),由于它出现在第三个索引位置,因此插入到结果数组的第三个索引位置。

欢迎提出任何建议和改进意见。

参考资料:

  1. Numpy_Docs

0
感谢@Hari_Sheldon的回复。现在,我已经看到了print对数组a所做的事情,但我仍然不明白为什么Python会将由列表指定的列作为行放置在最左边的位置。是否有任何参考资料来解释原因?
而且,在某些情况下,这种维度排列不会发生,即:
>>> a[0:1,:,[0,3]].shape
(1, 4, 2)

正如您所看到的,维度顺序保持不变,而不是将其排列为(2,4)!


你已经回答了其中需要评论的问题。如果你尝试一下a[0]a[0:1]之间的区别,你就能理解了。前者返回一个形状为**()的结果,而后者返回一个形状为(1,)的结果,对于1D**列表来说。 - Justice_Lords
是的,我理解保留退化维度的规则。但是,我不理解为什么保留一个退化维度可以防止数组排列。换句话说,为什么a[0:1,0,[0,3]]不能返回形状为(2,1,4)? - Liang Guo

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