使用行和列中的列表替换Numpy 2D Array的一部分

时间:2018-02-21 22:26:56

标签: python arrays python-3.x numpy replace

让我们首先导入numpy

import numpy as np

例如,我有一个矩阵A as,

A = np.identity(10)

我有另外两个矩阵,

B = np.random.sample((4, 4))
C = np.random.sample((6, 6))

另外,我有两个索引列表,

idx_1 = [1, 2, 4, 7]
idx_2 = [0, 3, 5, 6, 8, 9]

现在我想要用A和B替换idx_1 A行和A列的idx_2行和列。最后的A矩阵将是块对角矩阵。

实现这一目标的有效方法是什么?

我尝试如下但我没有改变A,我不知道为什么,但我也没有得到任何错误。

A[idx_1][:,idx_1] = B

1 个答案:

答案 0 :(得分:1)

In [99]: A = np.identity(10).astype(int)
In [100]: A
Out[100]: 
array([[1, 0, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 1, 0, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 1, 0, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 1, 0, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 1, 0, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 1, 0, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 1, 0, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 1, 0],
       [0, 0, 0, 0, 0, 0, 0, 0, 0, 1]])
In [101]: idx_1 = [1, 2, 4, 7]

我可以选择一组对角线值:

In [102]: A[idx_1, idx_1]
Out[102]: array([1, 1, 1, 1])
In [103]: A[idx_1, idx_1] = [10,20,30,40]
In [104]: A
Out[104]: 
array([[ 1,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0, 10,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0, 20,  0,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  1,  0,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0, 30,  0,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  1,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  1,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0, 40,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  1,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  1]])

但看起来你想要替换一个(4,4)值块。我们必须在索引上构造一对,broadcast与形状一起,即(4,1)数组与(1,4)数组。

In [105]: np.ix_(idx_1, idx_1)
Out[105]: 
(array([[1],
        [2],
        [4],
        [7]]), array([[1, 2, 4, 7]]))

In [106]: A[np.ix_(idx_1, idx_1)]
Out[106]: 
array([[10,  0,  0,  0],
       [ 0, 20,  0,  0],
       [ 0,  0, 30,  0],
       [ 0,  0,  0, 40]])
In [107]: A[np.ix_(idx_1, idx_1)] += 1
In [108]: A
Out[108]: 
array([[ 1,  0,  0,  0,  0,  0,  0,  0,  0,  0],
       [ 0, 11,  1,  0,  1,  0,  0,  1,  0,  0],
       [ 0,  1, 21,  0,  1,  0,  0,  1,  0,  0],
       [ 0,  0,  0,  1,  0,  0,  0,  0,  0,  0],
       [ 0,  1,  1,  0, 31,  0,  0,  1,  0,  0],
       [ 0,  0,  0,  0,  0,  1,  0,  0,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  1,  0,  0,  0],
       [ 0,  1,  1,  0,  1,  0,  0, 41,  0,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  1,  0],
       [ 0,  0,  0,  0,  0,  0,  0,  0,  0,  1]])

嵌套列表的等效索引是:

In [109]: A[[[1],[2],[4],[7]],[[1,2,4,7]]]
Out[109]: 
array([[11,  1,  1,  1],
       [ 1, 21,  1,  1],
       [ 1,  1, 31,  1],
       [ 1,  1,  1, 41]])

关于索引尝试:

In [110]: A[idx_1]   # A[idx_1,:]
Out[110]: 
array([[ 0, 11,  1,  0,  1,  0,  0,  1,  0,  0],
       [ 0,  1, 21,  0,  1,  0,  0,  1,  0,  0],
       [ 0,  1,  1,  0, 31,  0,  0,  1,  0,  0],
       [ 0,  1,  1,  0,  1,  0,  0, 41,  0,  0]])
In [111]: A[idx_1][:,idx_1]
Out[111]: 
array([[11,  1,  1,  1],
       [ 1, 21,  1,  1],
       [ 1,  1, 31,  1],
       [ 1,  1,  1, 41]])

In[111]分两步评估;选择第一行,然后选择列。

A[idx_1][:,idx_1] = B

B的值将替换Out[110]中的列。但这是A的价值副本,而不是view。因此,在使用numpy时,很好地掌握视图和副本之间以及基本索引和高级索引之间的区别非常重要。