Python numpy 4D阵列高级索引与示例
我正在阅读一些深入的学习代码。我在numpy数组中的高级索引上有问题。我正在测试的代码:Python numpy 4D阵列高级索引与示例,python,arrays,numpy,numpy-ndarray,Python,Arrays,Numpy,Numpy Ndarray,我正在阅读一些深入的学习代码。我在numpy数组中的高级索引上有问题。我正在测试的代码: import numpy x = numpy.arange(2 * 8 * 3 * 64).reshape((2, 8, 3, 64)) x.shape p1 = numpy.arange(2)[:, None] sd = numpy.ones(2 * 64, dtype=int).reshape((2, 64)) p4 = numpy.arange(128 // 2)[None, :] y = x[
import numpy
x = numpy.arange(2 * 8 * 3 * 64).reshape((2, 8, 3, 64))
x.shape
p1 = numpy.arange(2)[:, None]
sd = numpy.ones(2 * 64, dtype=int).reshape((2, 64))
p4 = numpy.arange(128 // 2)[None, :]
y = x[p1, :, sd, p4]
y.shape
为什么y
的形状是(2,64,8)
以下是上述代码的输出:
>>> x.shape
(2, 8, 3, 64)
>>> p1
array([[0], [1]])
>>> sd
array([[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])
>>> p4
array([[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63]])
>>> y.shape
(2, 64, 8)
我读到:
我认为这与广播有关:
x
形状是(2,8,3,64)
p1
很简单,它是数组([[0],[1]]),
只是指选择第一维度的ind0,1
。双阵列用于广播
p2
是:
,这意味着选择第二维度中的所有8个元素
p3
很复杂,它包含两个“列表”,可以从维度3的3个元素中选择一个,因此生成的新三维应该是1
p4
表示它选择了第四维中的所有64个元素
所以我认为y.shape
应该是(2,8,1,64)
但正确的答案是
(2,64,8)
。为什么?当我第一次在numpy中遇到花式索引时,我也遇到了同样的问题。简单的回答是没有什么诀窍:奇特的索引只是将元素选择到与索引形状相同的输出中。使用纯粹奇特的索引,输出数组的形状将与广播的索引数组相同()。输出的形状与输入的形状几乎没有任何关系,除非您也加入一个常规的切片索引()。你的情况是后者,这增加了混乱
让我们看看你的指数,看看发生了什么:
y = x[p1, :, sd, p4]
x.shape -> 2, 8, 3, 64
p1.shape -> 2, 1
sd.shape -> 2, 64
p4.shape -> 1, 64
关于如何进行的具体文档如下:
需要区分指数组合的两种情况:
- 高级索引由一个片段分隔,
或。例如省略号
x[arr1,:,arr2]
- 高级索引彼此相邻。例如
而不是xx[…,arr1,arr2,:]
,因为[arr1,:,1]
是这方面的高级索引1
p1
、sd
和p4
(2,64
),然后是第二维度的大小x
(8
)。这确实是您得到的:
>>> y.shape
(2, 64, 8)
非常感谢您的解释。我正在消化信息。我可以问几个后续问题吗?选择结果正确吗?代码正在尝试索引\u选择(2,8,3,64)的第三维度,因此我必须将轴从(2,64,8)交换到(2,8,1,64)?是否有更直接的方法获得所需的结果:(2,8,1,64)?谢谢!我不明白这句话“例如x[…,arr1,arr2,:],但不是x[arr1,:,1],因为1在这方面是一个高级索引。”,如果1是一个高级索引,那么x[arr1,:,1]与x[arr1,:,arr2]的情况不是一样吗?@mahon。第一个问题:完全正确。它警告你,`x[arr1,:,1]`与
x相同[arr1,:,arr2]
。如果所有索引都是切片,那么标量将充当切片,因此需要注意。@mahon。您可以用适当的切片替换生成的索引,然后一切都会解决。