python - How to convert matrix to block matrix using Numpy - Stack Overflow

admin2025-05-02  0

Say I have a matrix like

Matrix = [[A11, A12, A13, A14], [A21, A22, A23, A24], [A31, A32, A33, A34], [A41, A42, A43, A44]],

and suppose I want to convert it to a block matrix

[[A,B], [C,D]],

where

A = [[A11, A12], [A21, A22]] B = [[A13, A14], [A23, A24]] C = [[A31, A32], [A41, A42]] D = [[A33, A34], [A43, A44]].

What do I need to type to quickly extract the matrices A, B, C, and D?

Say I have a matrix like

Matrix = [[A11, A12, A13, A14], [A21, A22, A23, A24], [A31, A32, A33, A34], [A41, A42, A43, A44]],

and suppose I want to convert it to a block matrix

[[A,B], [C,D]],

where

A = [[A11, A12], [A21, A22]] B = [[A13, A14], [A23, A24]] C = [[A31, A32], [A41, A42]] D = [[A33, A34], [A43, A44]].

What do I need to type to quickly extract the matrices A, B, C, and D?

Share Improve this question asked Jan 2 at 13:03 Definitely Not a English MajorDefinitely Not a English Major 231 silver badge3 bronze badges 3
  • You might want to have a look at the answers to this question. – simon Commented Jan 2 at 13:15
  • Your 'block matrix' is a bit ambiguous. Is it supposed to be a (2,2,2,2) shaped array, or a (4,4) with rearranged values? Or is your primary goal the 4 (2,2) arrays? Then you don't need to reassemble them . Unpacking from the reshaped (4,4,4,4) array is enough. – hpaulj Commented Jan 2 at 19:24
  • @hpaulj I had the same concern. In LaTeX, I am looking for a way to get $Matrix = \begin{bmatrix} A & B \\ C & D \end{bmatrix}$ where $A, B, C, D$ are 2-by-2 matrices. No rearranging values. – Definitely Not a English Major Commented Jan 3 at 15:46
Add a comment  | 

3 Answers 3

Reset to default 4

Without using loops, you can reshape your array (and reorder the dimensions with moveaxis):

A, B, C, D = np.moveaxis(Matrix.reshape((2,2,2,2)), 1, 2).reshape(-1, 2, 2)

Or:

(A, B), (C, D) = np.moveaxis(Matrix.reshape((2,2,2,2)), 1, 2)

For a generic answer on an arbitrary shape:

x, y = Matrix.shape
(A, B), (C, D) = np.moveaxis(Matrix.reshape((2, x//2, 2, y//2)), 1, 2)

Output:

# A
array([['A11', 'A12'],
       ['A21', 'A22']], dtype='<U3')
# B
array([['A13', 'A14'],
       ['A23', 'A24']], dtype='<U3')
# C
array([['A31', 'A32'],
       ['A41', 'A42']], dtype='<U3')
# D
array([['A33', 'A34'],
       ['A43', 'A44']], dtype='<U3')

I would checkout the np.hsplit and np.vsplit functions. You'll find details in the numpy api reference.

If you do

blocks = [np.vsplit(i, 2) for i in np.hsplit(matrix, 2)]

then blocks will be an array containing your A,B,C and D matrices.

import numpy as np

matrix = np.array([
    ["A11", "A12", "A13", "A14"],
    ["A21", "A22", "A23", "A24"],
    ["A31", "A32", "A33", "A34"],
    ["A41", "A42", "A43", "A44"]
])


blocks = [np.vsplit(i, 2) for i in np.hsplit(matrix, 2)]

blocks_flat = np.array(blocks).reshape(-1, *blocks[0][0].shape)

A, B, C, D = blocks_flat

block_matrix = np.block([
    [A, B],
    [C, D]
])

print(A)
print(B)
print(C)
print(D)
print(block_matrix)

Another approach:

block_size = 2
blocks = [
   [matrix[i:i+block_size, j:j+block_size] for j in range(0, matrix.shape[1], block_size)]
   for i in range(0, matrix.shape[0], block_size)
]
A, B = blocks[0]
C, D = blocks[1]
block_matrix = np.block([
   [A, B],
   [C, D]
])

Furthermore:

block_size = 2

reshaped = matrix.reshape(2, block_size, 2, block_size).swapaxes(1, 2)

A, B, C, D = reshaped[0, 0], reshaped[0, 1], reshaped[1, 0],    reshaped[1, 1]
block_matrix = np.block([
   [A, B],
   [C, D]
])
转载请注明原文地址:http://www.anycun.com/QandA/1746118451a91923.html