繁体   English   中英

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

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

我试图将名为“S”的2D numpy数组的一部分替换为i和j的函数。 鉴于S为:

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

对于i = 0和j = 1,我可以使用以下语法访问元素行i和j以及列i和j:

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

现在,当我尝试用另一个相同维度的数组(tmp_arr)替换数组S的相同元素时,python不会给出错误,但它也没有做任何意味着S的元素保持不变并且没有显示错误消息。

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

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

而我得到的是相同的矩阵:

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

显然以下是可行的,但我正在寻找一个优雅的解决方案:

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]

感谢您的意见和经验。

您可以使用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]])

使用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

但与其他方法不同, S[np.ix_(...)] = ...不使用链式索引 ,因此调用S.__setitem__并且赋值会影响S 相反, S[:, [i, j]]返回S的子数组的副本 ,因此赋值给S[:, [i, j]][[i, j], :]仅影响该副本子阵列,而不是S本身。 由于不保留对子数组副本的引用,因此Python在分配完成后会抛弃副本,因此分配将丢失。 这就是为什么链式索引不适合分配给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