Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用索引替换二维numpy数组的一部分_Python_Numpy_Indexing_Multidimensional Array - Fatal编程技术网

Python 使用索引替换二维numpy数组的一部分

Python 使用索引替换二维numpy数组的一部分,python,numpy,indexing,multidimensional-array,Python,Numpy,Indexing,Multidimensional Array,我试图将名为“S”的2D numpy数组的一部分替换为I和j的函数。鉴于以下情况: >>> 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.,

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

>>> 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]
非常感谢您的评论和经验。

您可以使用以下方法构建所需的索引数组:

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_u(…)]=…
不使用链式索引,因此调用
S.\uuuu setitem_uu
,赋值影响
S
。相反,
S[:,[i,j]]
返回
S
子数组的副本,因此分配给
S[:,[i,j][[i,j],:]
只影响子数组的此副本,而不影响
S
本身。由于未维护对子数组的这个副本的引用,Python在赋值后会丢弃该副本,因此赋值将丢失。这就是为什么链式索引不适合分配给
S

为了确保他只抓取他要找的4个项目,你必须做
a[i:j+1:j-i,i:j+1:j-i]
,不是吗?当然要确保
j>i
。请注意i,j可以是非顺序的。例如i=0和j=2。换句话说,如果我要替换S[0,0]、S[0,2]、S[2,0]和S[2,2],那么我认为上述解决方案是行不通的。如果我错了,请纠正我。@Arian,你是对的-我的解决方案将替换连续范围。不幸的是,这不是我第一次误解。谢谢@unutbu的回答。这绝对有道理。
>>> 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.]])
>>>