如何解释以下行为:
import numpy as np
arr = np.zeros((3, 3))
li = [1,2]
print('output1:', arr[:, li].shape)
print('output2:', arr[:][li].shape)
>>output1: (3, 2)
>>output2: (2, 3)
我希望output2等于output1。
让我们使用一个不同的数组,这样更容易看到差异:
>>> arr = np.arange(9).reshape(3, 3)
>>> arr
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
第一种情况arr[:, li]
将选择第一个维度的所有元素(在这种情况下是所有行),然后用[1, 2]
对数组进行索引,这意味着只省略第一列:
array([[1, 2],
[4, 5],
[7, 8]])
因此,它的形状为(3,2)。
另一种情况arr[:]
将复制原始数组,因此它不会改变形状,因此它相当于arr[li]
,因此输出形状为(2, 3)
。一般来说,你应该避免对数组进行双索引,因为那样可能会创建两次视图,效率很低。
您正在得到正确的输出。
第一行
print('output1:', arr[:, li].shape)
您正在打印arr
中每个子数组的2nd
和3rd
元素,从而获得每个包含2
值的3
元素。
第二行
print('output2:', arr[:][li].shape)
您首先选择整个数组,然后从整个数组中选择2nd
和3rd
元素(每个元素本身包含3
元素),从而获得每个包含3
值的2
元素。
如果检查这段代码,可以看到差异-
import numpy as np
arr = np.arange(9).reshape(3, 3)
li = [1,2]
print('output1:', arr[:, li])
print('output2:', arr[:][li])
给出-
[[1 2]
[4 5]
[7 8]]
和
[[3 4 5]
[6 7 8]]
当你做arr[:, [1, 2]]
时,你说的是你想要取数组的所有行(:
指定了这一点),并从中取[1, 2]
列。
另一方面,当您执行arr[:]
时,您首先引用整个数组。
实际上,在第二种情况下,[1 2]
指向原始数组的行轴,而在第一种情况下,它指向列。