numpy 赋值不起作用

uda*_*day 4 numpy python-3.x

假设我有以下内容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)
Run Code Online (Sandbox Code Playgroud)

我想替换xby的子数组y并尝试了以下操作:

In[]: x[[0,2]][:,[1,3]]= y
Run Code Online (Sandbox Code Playgroud)

理想情况下,我希望这种情况发生:

In[]: x
Out[]: 
array([[1, -3, 3, -4, 5],
       [5, 2, 4, 1, 5],
       [6, -4, 2, -1, 1]], dtype=int16)
Run Code Online (Sandbox Code Playgroud)

赋值行没有给我任何错误,但是当我检查输出时x

 In[]: x
Run Code Online (Sandbox Code Playgroud)

我发现这x没有改变,即作业没有发生。

我怎样才能完成这项任务?为什么任务没有完成?

YXD*_*YXD 5

“花式索引”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
>>>
Run Code Online (Sandbox Code Playgroud)

现在您可以使用花式索引来设置数组值,但在嵌套索引时则不能。

您可以使用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)
>>>
Run Code Online (Sandbox Code Playgroud)

您还可以使其与广播的花哨索引一起使用(如果这甚至是术语),但它并不漂亮

>>> 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)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,目前 NumPy 讨论邮件列表上有一些关于更好地支持“正交”索引的有趣讨论,因此将来这可能会变得更容易。