让我们把y
变得更有趣一点:
In [915]: y = np.arange(10).reshape(2,5);y, y.base
Out[915]:
(array([[0, 1, 2, 3, 4],
[5, 6, 7, 8, 9]]),
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
它是一维数组中的view
个.
现在使用高级索引:
In [916]: b = y[:,[0,2,4]];b, b.base
Out[916]:
(array([[0, 2, 4],
[5, 7, 9]]),
array([[0, 5],
[2, 7],
[4, 9]]))
In [917]: b.strides, b.base.strides
Out[917]: ((4, 8), (8, 4))
正如我们从索引中预期的那样,b
是一个(2,3)数组,但它实际上是一个(3,2)数组的转置.显然,numpy
正在使用列表索引(第二维) Select 值,并将切片维度放在最后.然后,它会转置以获得所需的形状.这暗示了为什么混合高级索引和基本索引可能会产生意外的形状(如其他SO中所述和文档所述).
在任何情况下,我都找不到一种方法来测试b
来验证它不是y
的view
--除非通过比较base
个属性.最简单的事情就是接受文档所声称的它是副本--只是不是"直接"副本.
我们可以使用基本索引得到相同的数组--得到的是view
,即y.base
:
In [918]: c = y[:,::2]; c, c.base
Out[918]:
(array([[0, 2, 4],
[5, 7, 9]]),
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]))
还有其他几种获得简单副本的方法:
In [924]: d = y[[0,1], ::2]; d, d.base
Out[924]:
(array([[0, 2, 4],
[5, 7, 9]]),
None)
In [925]: d = y[[[0],[1]], [0,2,4]]; d, d.base
Out[925]:
(array([[0, 2, 4],
[5, 7, 9]]),
None)