numpy 切片和索引不同的结果

numpy slicing and indexing different results

在numpy中,通过任何切片、掩码或花哨的索引操作获得的子数组只是原始数组的视图,可以证明如下:

$ python3
Python 3.5.2 (default, Nov 23 2017, 16:37:01) 
[GCC 5.4.0 20160609] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy as np
>>> np.__version__
'1.11.0'

>>> a = np.arange(3); a[:2] = 111; a
array([111, 111,   2])

>>> a = np.arange(3); a[a<2] = 111; a
array([111, 111,   2])

>>> a = np.arange(3); a[[0,1]] = 111; a
array([111, 111,   2])

在上面的例子中,整个子数组都被赋值给了。然而,如果我们分配给子数组的一个元素,切片操作的结果仍然表现为视图,而屏蔽和花式索引操作的结果表现为独立的副本:

>>> a = np.arange(3); a[:2][0] = 111; a
array([111,   1,   2])

>>> a = np.arange(3); a[a<2][0] = 111; a
array([0, 1, 2])

>>> a = np.arange(3); a[[0,1]][0] = 111; a
array([0, 1, 2])

这是 numpy 中的错误,还是设计使然?如果是设计使然,那么这种不一致的证据是什么?

这不是错误。就您将切片对象传递给 Numpy 数组而言,返回的子数组是原始项的视图,这意味着即使切片赋值或单个项赋值也会更改原始数组。但在其他情况下,返回的结果不是视图。实际上,它是所选切片的浅视图(副本),它仅支持切片分配,就像 Python 中的其他可变对象所支持的那样。

documentation中也提到了:

[...] As with index arrays, what is returned is a copy of the data, not a view as one gets with slices.