numpy 切片和索引不同的结果
Posted
技术标签:
【中文标题】numpy 切片和索引不同的结果【英文标题】:numpy slicing and indexing different results 【发布时间】:2018-10-17 05:54:00 【问题描述】:在通过任何切片、掩码或花式索引操作获得的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 中的错误,还是设计使然?如果是有意为之,那么这种不一致的依据是什么?
【问题讨论】:
【参考方案1】:这不是错误。只要您将切片对象传递给 Numpy 数组,返回的子数组就是原始项目的视图,这意味着即使切片分配或单个项目分配也会改变原始数组。但在其他情况下,返回的结果不是视图。事实上,它是所选切片的浅视图(副本),它只支持切片分配,就像 Python 中的其他可变对象一样。
documentation中也提到过:
[...] 与索引数组一样,返回的是数据的副本,而不是切片时的视图。
【讨论】:
好的,这意味着我还不太了解 Python 中赋值的工作原理。现在我的第一印象是a[i]
的评估方式不同,具体取决于它是否出现在赋值运算符的左侧。重读文档,我发现对于用户定义的对象,赋值 object[expr] = ...
是通过 object.__setitem__ 评估的,而在其他情况下则使用 object.__getitem__。
@Leon 确实如此。这就是在 Python 中设置项目和获取项目的方式。以上是关于numpy 切片和索引不同的结果的主要内容,如果未能解决你的问题,请参考以下文章