python索引不会更改numpy数组

时间:2019-10-16 10:00:11

标签: python numpy

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]]

那么,为什么第二种方法没有更改数组,而第一种和第三种方法起作用呢?我用谷歌搜索了很多答案,但我还是不明白。

1 个答案:

答案 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中。

>

那么情况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
)