Approach #1
Classic case of numpy.kron
-
np.kron(np.eye(r,dtype=int),a) # r is number of repeats
Sample run -
In [184]: a
Out[184]:
array([[1, 2, 3],
[3, 4, 5]])
In [185]: r = 3 # number of repeats
In [186]: np.kron(np.eye(r,dtype=int),a)
Out[186]:
array([[1, 2, 3, 0, 0, 0, 0, 0, 0],
[3, 4, 5, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 2, 3, 0, 0, 0],
[0, 0, 0, 3, 4, 5, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 2, 3],
[0, 0, 0, 0, 0, 0, 3, 4, 5]])
Approach #2
Another efficient one with diagonal-viewed-array-assignment
-
def repeat_along_diag(a, r):
m,n = a.shape
out = np.zeros((r,m,r,n), dtype=a.dtype)
diag = np.einsum('ijik->ijk',out)
diag[:] = a
return out.reshape(-1,n*r)
Sample run -
In [188]: repeat_along_diag(a,3)
Out[188]:
array([[1, 2, 3, 0, 0, 0, 0, 0, 0],
[3, 4, 5, 0, 0, 0, 0, 0, 0],
[0, 0, 0, 1, 2, 3, 0, 0, 0],
[0, 0, 0, 3, 4, 5, 0, 0, 0],
[0, 0, 0, 0, 0, 0, 1, 2, 3],
[0, 0, 0, 0, 0, 0, 3, 4, 5]])