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?
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]
])
(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