I'm looking for a function capable of taking a m x n
array, which repeats each row n times over a identity-like grid of m size.
For demo:
input = [[a1, b1, c1],
[a2, b2, c2]]
output = [[a1, b1, c1, 0, 0, 0],
[a1, b1, c1, 0, 0, 0],
[a1, b1, c1, 0, 0, 0],
[ 0, 0, 0, a2, b2, c2],
[ 0, 0, 0, a2, b2, c2],
[ 0, 0, 0, a2, b2, c2]]
Last time I asked something similar I was told of the Kronecker product, is there some similar function?
While looking similar, it appears to me that the given problem cannot be solved using a Kronecker product: with the latter, you could only manage to get repetitions of your complete input matrix as blocks of the result matrix.
I stand corrected: For a solution that employs the Kronecker product, see @ThomasIsCoding's answer.
In any case, what you need is the individual rows, repeated, as blocks of the result matrix. So that is what the code below does: it constructs a block matrix from the rows, using scipy.linalg.block_diag()
, then repeats them as required, using numpy.repeat()
. Note that block_diag()
expects individual blocks as individual arguments, which is why a
is unpacked with the *
prefix.
import numpy as np
import scipy
a = np.asarray([[11, 21, 31], [21, 22, 32], [31, 32, 33]])
print(a)
# [[11 21 31]
# [21 22 32]
# [31 32 33]]
blocked = scipy.linalg.block_diag(*a)
print(blocked)
# [[11 21 31 0 0 0 0 0 0]
# [ 0 0 0 21 22 32 0 0 0]
# [ 0 0 0 0 0 0 31 32 33]]
result = np.repeat(blocked, a.shape[1], axis=0)
print(result)
# [[11 21 31 0 0 0 0 0 0]
# [11 21 31 0 0 0 0 0 0]
# [11 21 31 0 0 0 0 0 0]
# [ 0 0 0 21 22 32 0 0 0]
# [ 0 0 0 21 22 32 0 0 0]
# [ 0 0 0 21 22 32 0 0 0]
# [ 0 0 0 0 0 0 31 32 33]
# [ 0 0 0 0 0 0 31 32 33]
# [ 0 0 0 0 0 0 31 32 33]]