import numpy as np
data = np.zeros((5,3))
In [44]: data
Out[44]:
array([[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
In [45]: data[[0,1,2]] = 2
In [46]: data
Out[46]:
array([[ 2., 2., 2.],
[ 2., 2., 2.],
[ 2., 2., 2.],
[ 0., 0., 0.],
[ 0., 0., 0.]])
In [47]: data[[0,1,2]][2]
Out[47]: array([ 2., 2., 2.])
In [48]: data[[0,1,2]][2] = 3
In [49]: data[[0,1,2]][2]
Out[49]: array([ 2., 2., 2.])
我期待最后的结果是[3.,3.,3。]。为什么用双指数替换元素是不行的?有没有办法使用双索引更改数组的元素?
答案 0 :(得分:2)
在
data[[0,1,2]][2] = 3
data[[0,1,2]]
是data
的一部分副本,而不是view
的副本。表达式正在修改该副本,而不是data
本身。
In [298]: data=np.arange(15).reshape(5,3)
In [299]: data[[0,1,2]]
Out[299]:
array([[0, 1, 2],
[3, 4, 5],
[6, 7, 8]])
In [300]: data[[0,1,2]][2]
Out[300]: array([6, 7, 8])
此作业有效:
data[[0,1,2]] = 2
因为'高级索引'就在=
之前。在第一种情况下,它被另一个索引层分开。
答案 1 :(得分:2)
Python评估data[i][j] = x
的方式是首先评估tmp = data.__getitem__(i)
,然后在该临时对象上调用tmp.__setitem__(j, x)
。在numpy的情况下,当您使用列表对数组进行索引来评估data[[1,2,3]]
时,您将创建一个新数组,其中包含这些位置的数据副本。我们无法在data
上创建视图,因为列表可能包含分散的索引,甚至是重复的索引。因此tmp
对象未连接到原始data
对象。分配tmp[2] = 3
发生了,但随后tmp
被丢弃。
答案 2 :(得分:0)
这很奇怪。它必须与numpy.array的结构相关。从我对numpy的经验来看,数组切片是用数据[outerindex,innerindex]而不是传统的Python列表数据[outerindex] [innerindex]完成的。
如果你这样做
data[[0,1,2],2] = 3
您可以按照预期修改数据:
>>>data
array([ 2., 2., 3.],
[ 2., 2., 3.],
[ 2., 2., 3.],
[ 0., 0., 0.],
[ 0., 0., 0.])