Reputation: 630
I have a matrix, say 3 x 3
x= np.arange(0,9,1).reshape((3,3))
and I want to get a bigger matrix (9x9) built according to the following simple rule:
the first three rows of the new matrix are identical, and made from the first row of x and zeros to the end.
The second three rows are identical and are made from the second row of x by three 0s, then x, then 0s to the end of the row, and so on. Something like this.
0 1 2 0 0 0 0 0 0
0 1 2 0 0 0 0 0 0
0 1 2 0 0 0 0 0 0
0 0 0 3 4 5 0 0 0
0 0 0 3 4 5 0 0 0
0 0 0 3 4 5 0 0 0
0 0 0 0 0 0 6 7 8
0 0 0 0 0 0 6 7 8
0 0 0 0 0 0 6 7 8
Is there a way to do it in a pythonic way? I have tried to see if by using numpy.kron / numpy.repeat but I don't think this is the way.
In particular I thought first to get a matrix 9*3 by
x=np.repeat(x,3)
and then try to complete it with zeros by using np.kron, but it did not work.
Upvotes: 0
Views: 67
Reputation: 2406
Not sure how pythonic it is but my idea is to use list comprehension to iterate through each row and np.pad it based on changing parameters:
import numpy as np
x = np.arange(0,9,1).reshape((3,3))
a = x.shape[1] # length of original rows | you can hardcode to 3
b = x.shape[0]*a - a # number of cells you will pad each row with | you can hardcode it to 6
repeat = 3 # how many times each row should be repeated
x_padded = [np.pad(row, (i*a, b-i*a)) for i, row in enumerate(x)]
x_out = np.repeat(x_padded, repeat, axis=0)
print(x_out)
Output:
[[0 1 2 0 0 0 0 0 0]
[0 1 2 0 0 0 0 0 0]
[0 1 2 0 0 0 0 0 0]
[0 0 0 3 4 5 0 0 0]
[0 0 0 3 4 5 0 0 0]
[0 0 0 3 4 5 0 0 0]
[0 0 0 0 0 0 6 7 8]
[0 0 0 0 0 0 6 7 8]
[0 0 0 0 0 0 6 7 8]]
Upvotes: 1
Reputation: 2719
You can use block_diag from scipy.linalg.
"""
>>> print(answer)
[[0 1 2 0 0 0 0 0 0]
[0 1 2 0 0 0 0 0 0]
[0 1 2 0 0 0 0 0 0]
[0 0 0 3 4 5 0 0 0]
[0 0 0 3 4 5 0 0 0]
[0 0 0 3 4 5 0 0 0]
[0 0 0 0 0 0 6 7 8]
[0 0 0 0 0 0 6 7 8]
[0 0 0 0 0 0 6 7 8]]
"""
from scipy.linalg import block_diag
import numpy as np
x = np.arange(9).reshape(3, 3)
answer = block_diag(*np.array_split(x.repeat(3, axis=0), 3))
Upvotes: 2