用另一个小矩阵替换numpy中矩阵的部分元素

39 投票
5 回答
43804 浏览
提问于 2025-04-29 00:43

我刚接触Numpy,想要替换一个矩阵的部分内容。比如,我有两个矩阵,A和B,都是用numpy生成的。

In [333]: A = ones((5,5))

In [334]: A
Out[334]: 
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])

In [335]: B
Out[335]: 
array([[ 0.1,  0.2],
       [ 0.3,  0.4]])

最后,我想把A变成下面这个矩阵。

In [336]: A
Out[336]: 
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  0.1,  0.2],
       [ 1.,  1.,  1.,  0.3,  0.4]])

或者变成下面这个。

In [336]: A
Out[336]: 
array([[ 1.,  1.,  1.,  0.1,  0.2],
       [ 1.,  1.,  1.,  0.3,  0.4],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])

我试过这样做,但没成功。现在我完全不知道该怎么办了 :(

A[[0,1],:][:,[3,4]] = B

我甚至还试过这样做。

A[[0,1],:][:,[3,4]] = 1

想检查这四个单元格是否被改变了。你有什么建议吗?

暂无标签

5 个回答

1

对于不连续的行或列的情况,你可以使用一个临时变量 C 来用 B 替换 A 的一部分:

A = np.ones((5,5))
B = np.array([[0.1,0.2],[0.3,0.4]])
row_loc=[0,3]
col_loc=[1,4]
C = A[row_loc,:]
C[:,col_loc] = B
A[row_loc,:] = C
A

Output:
array([[1. , 0.1, 1. , 1. , 0.2],
       [1. , 1. , 1. , 1. , 1. ],
       [1. , 1. , 1. , 1. , 1. ],
       [1. , 0.3, 1. , 1. , 0.4],
       [1. , 1. , 1. , 1. , 1. ]])
2

下面这个函数可以替换矩阵中任意不连续的部分,用另一个矩阵来替换。

def replace_submatrix(mat, ind1, ind2, mat_replace):
  for i, index in enumerate(ind1):
    mat[index, ind2] = mat_replace[i, :]
  return mat

现在给大家举个例子。我们将一个空的4 x 4数组x中,索引为[1, 3]和[0, 3]的部分(也就是ind1ind2)替换成一个包含4个不同值的2 x 2数组y

x = np.full((4, 4), 0)
x
array([[0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0],
       [0, 0, 0, 0]])

y = np.array([[1, 2], [5, 9]])
y
array([[1, 2],
       [5, 9]])

ind1 = [1, 3]
ind2 = [0, 3]
res = replace_submatrix(x, ind1, ind2, y)  
res  
array([[0, 0, 0, 0],
       [1, 0, 0, 2],
       [0, 0, 0, 0],
       [5, 0, 0, 9]])
7

对于第一个:

In [13]: A[-B.shape[0]:, -B.shape[1]:] = B                              

In [14]: A
Out[14]: 
array([[ 1. ,  1. ,  1. ,  1. ,  1. ],                                  
       [ 1. ,  1. ,  1. ,  1. ,  1. ],                                  
       [ 1. ,  1. ,  1. ,  1. ,  1. ],                                  
       [ 1. ,  1. ,  1. ,  0.1,  0.2],                                  
       [ 1. ,  1. ,  1. ,  0.3,  0.4]])   

对于第二个:

In [15]: A = np.ones((5,5))                                             

In [16]: A[:B.shape[0], -B.shape[1]:] = B                               

In [17]: A
Out[17]: 
array([[ 1. ,  1. ,  1. ,  0.1,  0.2],                                  
       [ 1. ,  1. ,  1. ,  0.3,  0.4],                                  
       [ 1. ,  1. ,  1. ,  1. ,  1. ],                                  
       [ 1. ,  1. ,  1. ,  1. ,  1. ],                                  
       [ 1. ,  1. ,  1. ,  1. ,  1. ]])   
8

一般来说,比如说对于不连续的行或列,可以使用 numpy.putmask(a, mask, values) 这个方法。它的作用是把数组 a 中,符合条件的地方(也就是 mask 中为真的地方)替换成 values 中对应的值。

举个例子:

In [1]: a = np.zeros((3, 3))
Out [1]: a
array([[0., 0., 0.],
       [0., 0., 0.],
       [0., 0., 0.]])

In [2]: values = np.ones((2, 2))
Out [2]: values
array([[1., 1.],
       [1., 1.]])

In [3]: mask = np.zeros((3, 3), dtype=bool)
In [4]: mask[0,0] = mask[0,1] = mask[1,1] = mask[2,2] = True

Out [4]: mask
array([[ True,  True, False],
       [False,  True, False],
       [False, False,  True]])

In [5] np.putmask(a, mask, values)
Out [5] a
array([[1., 1., 0.],
       [0., 1., 0.],
       [0., 0., 1.]])
39

下面是你可以这样做的方法:

>>> A[3:5, 3:5] = B
>>> A
array([[ 1. ,  1. ,  1. ,  1. ,  1. ],
       [ 1. ,  1. ,  1. ,  1. ,  1. ],
       [ 1. ,  1. ,  1. ,  1. ,  1. ],
       [ 1. ,  1. ,  1. ,  0.1,  0.2],
       [ 1. ,  1. ,  1. ,  0.3,  0.4]])

撰写回答