numpy:子数组中不能赋值吗?
import numpy as np
a = np.zeros((3,2))
ind_row = np.array([0,1])
a[ind_row, 1]=3
现在,a
的状态是我们预期的:
[[ 0. 3.]
[ 0. 3.]
[ 0. 0.]]
我想给a[ind_row, 1]
的一个子数组赋值,并希望能像这样进行操作:
a[ind_row, 1][1] = 5
但是,这样做并没有改变a
!我为什么会有这样的期待呢?
1 个回答
10
这里的问题是,高级索引会创建数组的一个副本,而只有这个副本会被修改。(这和基本索引不同,基本索引是直接查看原始数据。)
当你直接给一个高级切片赋值时
a[ind_row, 1] = 3
不会创建副本,但当使用
a[ind_row, 1][1] = 5
时,a[ind_row, 1]
部分会创建一个副本,而[1]
部分则是在这个临时副本上进行索引。副本确实被改变了,但因为你没有持有它的引用,所以你看不到这些变化,而且它会立即被垃圾回收。
这就像切片标准的Python列表(这也会创建副本):
>>> a = range(5)
>>> a[2:4] = -1, -2
>>> a
[0, 1, -1, -2, 4]
>>> a[2:4][1] = -3
>>> a
[0, 1, -1, -2, 4]
对于这个简单的情况,解决问题的方法显而易见是
a[ind_row[1], 1] = 5
更复杂的情况也可以用类似的方式重写。