假设我有以下numpy.array
:
In[]: x
Out[]:
array([[1, 2, 3, 4, 5],
[5, 2, 4, 1, 5],
[6, 7, 2, 5, 1]], dtype=int16)
In[]: y
Out[]:
array([[-3, -4],
[-4, -1]], dtype=int16)
我希望将x
的子数组替换为y
并尝试以下操作:
In[]: x[[0,2]][:,[1,3]]= y
理想情况下,我希望这种情况发生:
In[]: x
Out[]:
array([[1, -3, 3, -4, 5],
[5, 2, 4, 1, 5],
[6, -4, 2, -1, 1]], dtype=int16)
分配行不会给我任何错误,但当我检查x
In[]: x
我发现x
没有改变,即分配没有发生。
我该如何完成这项任务?为什么这项任务没有发生?
答案 0 :(得分:2)
"花式索引" x[[0,2]][:,[1,3]]
返回数据的副本。使用切片进行索引会返回视图。分配确实发生了,但是对x
的副本(实际上是...的副本的副本)。
在这里,我们看到索引返回一个副本:
>>> x[[0,2]]
array([[1, 2, 3, 4, 5],
[6, 7, 2, 5, 1]], dtype=int16)
>>> x[[0,2]].base is x
False
>>> x[[0,2]][:, [1, 3]].base is x
False
>>>
现在您可以使用花式索引来设置数组值,但不能在嵌套索引时使用。
您可以使用np.ix_
生成索引并执行分配:
>>> x[np.ix_([0, 2], [1, 3])]
array([[2, 4],
[7, 5]], dtype=int16)
>>> np.ix_([0, 2], [1, 3])
(array([[0],
[2]]), array([[1, 3]]))
>>> x[np.ix_([0, 2], [1, 3])] = y
>>> x
array([[ 1, -3, 3, -4, 5],
[ 5, 2, 4, 1, 5],
[ 6, -4, 2, -1, 1]], dtype=int16)
>>>
你也可以使用广播的花式索引(如果这甚至是术语),但它不是很漂亮
>>> x[[0, 2], np.array([1, 3])[..., None]] = y
>>> x
array([[ 1, -3, 3, -4, 5],
[ 5, 2, 4, 1, 5],
[ 6, -4, 2, -1, 1]], dtype=int16)
顺便说一句,目前在NumPy Discussion邮件列表上有一些interesting discussion更好地支持" orthogonal"索引,以便将来可能会变得更容易。