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]]
那么为什么第二种方式没有改变数组,而第一种方式和第三种方式有效呢?我用谷歌搜索了很多答案,但我还是不明白。
最佳答案
这很复杂。
基本上,你在做 advanced indexing在情况 1 和 2 中,在情况 3 中进行基本索引。有关高级索引状态的 NumPy 文档:
Advanced indexing always returns a copy of the data (contrast with basic slicing that returns a view).
所以我们已经知道case 2和case 3的区别了,case 2基本等同于
b = a[[0, 1]]
b[0, 0] = 98
由于高级索引创建了一个副本,b
不再链接到 a
,并且不会反射(reflect)更改。在情况 3 中,我们有
b = a[0:2]
b[0, 0] = 99
其中 b
现在是 a
的 View (基本索引),因此 b
中的更改被反射(reflect)在 a
中。
那么情况 1 是怎么回事?
本质区别在于您不能将其拆分为赋值 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
)
关于python 索引不改变 numpy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58410641/