在numpy中,通过切片、掩码或花式索引操作获得的子数组仅是对原始数组的视图。这可以通过以下方式进行演示:
在上面的例子中,整个子数组都被赋值了。但是如果我们将值赋给子数组的一个元素,则切片操作的结果仍然表现为视图,而掩码和花式索引操作的结果则表现为独立的副本:
这是numpy的一个bug吗?还是故意设计成这样呢?如果是故意设计成这种不一致性的话,有什么理由可以证明呢?
$ 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的一个bug吗?还是故意设计成这样呢?如果是故意设计成这种不一致性的话,有什么理由可以证明呢?
a[i]
的求值方式取决于它是否出现在赋值运算符的左侧。重新阅读文档后,我发现对于用户定义的对象,赋值object[expr] = ...
通过object.setitem进行求值,而在其他情况下,则使用object.getitem。 - Leon