How to replace a small matrix in a larger matrix with different rows and columns

Viewed 128

Suppose we have a large A(n*n) and a small B(m*m) matrices (m<n). Also, there is a set J with the size of m which are values from {1,2,3,...,n}. I want to replace the matrix B in rows and columns of matrix A such that the first row (column) of matrix B is replaced in the first element of set J. For example,

   [[1 1 1 1 1],
    [1 1 1 1 1],
A = [1 1 1 1 1],
    [1 1 1 1 1],
    [1 1 1 1 1]]

and

J = [1, 3, 5]
B =[[2 3 4],
    [5 6 7],
    [8 9 10]]

Then, the result will be:

   [[2 1 3 1 4],
    [1 1 1 1 1],
A = [5 1 6 1 7],
    [1 1 1 1 1],
    [8 1 9 1 10]]
3 Answers

Try this:

tmp = A[J-1]
tmp[:, J-1] = B
A[J-1] = tmp
>>> A
array([[ 2,  1,  3,  1,  4],
       [ 1,  1,  1,  1,  1],
       [ 5,  1,  6,  1,  7],
       [ 1,  1,  1,  1,  1],
       [ 8,  1,  9,  1, 10]])

Why the roundtrip using a tmp variable, where the more intuitive way would be A[J-1][:, J-1] = B? That is because A[J-1][:, J-1] cannot be a view of A (there is no simple striding of A that will give you that sub-array), and thus it is instead a view of a copy of A[J-1] (which you can use as lvalue but will be lost). So, instead, we explicitly "put back into A" the value of tmp.

will the obvious way of doing things cut it?

A = [[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]]
J = [1, 3, 5]
B = [[2, 3, 4],
     [5, 6, 7],
     [8, 9, 10]]

print(A)
for rB,rA in enumerate(J):
    for cB,cA in enumerate(J):
        A[rA-1][cA-1] = B[rB][cB]   #list indices are 0-based
print(A)
exit(-1)


#ok, let`s do it functional way
J = list(map(lambda x:x-1, J))  # convert inex array 0-based indices
lira = lambda l,i,r,a: r if type(l) is not list else lira(l[:i[0]] + [lira(l[i[0]], a, r[0], a)] + l[i[0] + 1:], i[1:], r[1:], a) if i else l
A = lira(A,J,B,J)
print(A)

You can use built-in np.ix_ for this purpose:

A[np.ix_(J-1,J-1)] = B

output:

array([[ 2.,  1.,  3.,  1.,  4.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 5.,  1.,  6.,  1.,  7.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 8.,  1.,  9.,  1., 10.]])
Related