import numpy as np
a = np.array([[0, 1, 2],
[0, 1, 2],
[1, 1, 2]])
a[[0, 1]] = 100 # Changed
print(a)
a[[0, 1]][0, 0] = 98 # Not Changed
print(a)
a[0:2][0, 0] = 99 # Changed
print(a)
输出为:
# first
[[100 100 100]
[100 100 100]
[ 1 1 2]]
# second
[[100 100 100]
[100 100 100]
[ 1 1 2]]
# third
[[ 99 100 100]
[100 100 100]
[ 1 1 2]]
那么,为什么第二种方法没有更改数组,而第一种和第三种方法起作用呢?我用谷歌搜索了很多答案,但我还是不明白。
答案 0 :(得分:5)
这很复杂。
基本上,情况1和2是advanced indexing,情况3是基本索引。高级索引状态的NumPy文档为:
高级索引总是返回数据的副本(与返回视图的基本切片相反)。
所以我们已经知道情况2和3之间的区别。情况2基本上等同于
b = a[[0, 1]]
b[0, 0] = 98
由于高级索引创建了副本,因此b
不再链接到a
,并且更改也不会反映出来。在第3种情况下,我们有
b = a[0:2]
b[0, 0] = 99
其中b
现在是a
(基本索引)的视图,因此b
的变化反映在a
中。
本质区别是您不能将其拆分为分配b = ...
和后续的setitem
操作。相反,您直接对索引上的结果执行setitem
,但不会创建副本(仅getitem
用于副本)。因此,我们得到了与案例2相同的行为。
以下说明了这一点:
案例1 等同于
setitem(a, [0, 1], 100) # operates directly on a
案例2 等同于
setitem(
getitem(a, [0, 1]), # this is a copy
[0, 0],
98
)