简体   繁体   English

使用索引替换2D numpy数组的一部分

[英]Replacing part of a 2D numpy array using indexing

I am trying to replace part of a 2D numpy array named "S" as a function of i and j. 我试图将名为“S”的2D numpy数组的一部分替换为i和j的函数。 Given S as: 鉴于S为:

>>> S
Out[1]: 
array([[ 1.,  0.,  0.],
      [ 0.,  3.,  0.],
      [ 0.,  0.,  9.]]

for i= 0 and j= 1, I can access elements row i and j and column i and j using the following syntax: 对于i = 0和j = 1,我可以使用以下语法访问元素行i和j以及列i和j:

>>> S[:, [i, j]][[i, j], :]
Out[2]: 
array([[ 1.,  0.],
      [ 0.,  3.]])

Now when I try to replace the same elements of array S with another array of same dimensions (tmp_arr) python does not give an error but it also does not do anything meaning that the elements of S remain unchanged and no error message is displayed. 现在,当我尝试用另一个相同维度的数组(tmp_arr)替换数组S的相同元素时,python不会给出错误,但它也没有做任何意味着S的元素保持不变并且没有显示错误消息。

>>> tmp_arr
Out[3]: 
array([[ 555.,  0.],
       [ 0.,  555.]])

>>> S[:, [i, j]][[i, j], :] = tmp_arr

and what I get is the same matrix: 而我得到的是相同的矩阵:

>>> S
Out[4]: 
array([[ 1.,  0.,  0.],
      [ 0.,  3.,  0.],
      [ 0.,  0.,  9.]])

Obviously the following would work but I am looking for an elegant solution: 显然以下是可行的,但我正在寻找一个优雅的解决方案:

S[i, i] = tmp_arr[0, 0]
S[i, j] = tmp_arr[0, 1]
S[j, i] = tmp_arr[1, 0]
S[j, j] = tmp_arr[1, 1]

I appreciate your comments and experiences. 感谢您的意见和经验。

You could use np.ix_ to construct the desired index arrays: 您可以使用np.ix_来构造所需的索引数组:

In [91]: S[np.ix_([i,j],[i,j])]
Out[91]: 
array([[1, 0],
       [0, 3]])

In [92]: tmp_arr = np.eye(2)*555

In [93]: tmp_arr
Out[93]: 
array([[ 555.,    0.],
       [   0.,  555.]])

In [94]: S[np.ix_([i,j],[i,j])] = tmp_arr

In [95]: S
Out[95]: 
array([[555,   0,   0],
       [  0, 555,   0],
       [  0,   0,   9]])

Using np.ix_ is good for making assignments to S , but note there are faster ways to select the subarray: 使用np.ix_很适合对S进行赋值,但请注意有更快的方法来选择子数组:

In [99]: %timeit S.take([i, j], axis=1).take([i, j], axis=0)
100000 loops, best of 3: 3.32 µs per loop
In [97]: %timeit S[:, [i, j]][[i, j], :]
100000 loops, best of 3: 8.8 µs per loop
In [96]: %timeit S[np.ix_([i,j],[i,j])]
100000 loops, best of 3: 13 µs per loop

But unlike these other methods, S[np.ix_(...)] = ... does not use chained indexing , so S.__setitem__ gets called and the assignment affects S . 但与其他方法不同, S[np.ix_(...)] = ...不使用链式索引 ,因此调用S.__setitem__并且赋值会影响S In contrast, S[:, [i, j]] returns a copy of a subarray of S , so assigning to S[:, [i, j]][[i, j], :] affects only this copy of the subarray, not S itself. 相反, S[:, [i, j]]返回S的子数组的副本 ,因此赋值给S[:, [i, j]][[i, j], :]仅影响该副本子阵列,而不是S本身。 Since no reference to this copy of the subarray is maintained, Python throws away the copy after the assignment is made, so the assignment is lost. 由于不保留对子数组副本的引用,因此Python在分配完成后会抛弃副本,因此分配将丢失。 That is why chained indexing is no good for assigning to S . 这就是为什么链式索引不适合分配给S

>>> a
array([[ 1.,  0.,  0.],
       [ 0.,  3.,  0.],
       [ 0.,  0.,  9.]])
>>> i, j = 0 , 1
>>> a[i:j+1,i:j+1] = np.arange(100, 104).reshape(2,2)
>>> a
array([[ 100.,  101.,    0.],
       [ 102.,  103.,    0.],
       [   0.,    0.,    9.]])
>>> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM