I'll start with a few general observations
For numpy arrays, we usually use the syntax [,] rather than [] [] final [6 * i + k] [6 * j + l] final [6 * i + k, 6 * j + l]
For new arrays built from others, we often use things like reshape and slicing so that we can add them together as blocks, rather than with iterative loops
As a simple example, the following differences can be made:
y = x[1:] - x[:-1]
As for the name, โmatrix creationโ is clearer. "load" makes more sense to read data from a file, as in np.loadtxt .
==================
So, with N=1 ,
In [171]: A=np.arange(0,9).reshape(3,3) In [172]: B=np.arange(10,19).reshape(3,3) In [173]: C=np.arange(20,29).reshape(3,3) In [174]: D=np.arange(30,39).reshape(3,3) In [178]: final Out[178]: array([[ 0, 1, 2, 30, 31, 32], [ 3, 4, 5, 33, 34, 35], [ 6, 7, 8, 36, 37, 38], [20, 21, 22, 10, 11, 12], [23, 24, 25, 13, 14, 15], [26, 27, 28, 16, 17, 18]])
What can be created with a single bmat call:
In [183]: np.bmat([[A,D],[C,B]]).A Out[183]: array([[ 0, 1, 2, 30, 31, 32], [ 3, 4, 5, 33, 34, 35], [ 6, 7, 8, 36, 37, 38], [20, 21, 22, 10, 11, 12], [23, 24, 25, 13, 14, 15], [26, 27, 28, 16, 17, 18]])
bmat uses a combination of hstack and vstack . It also creates np.matrix , hence the need for .A . @Divakar's solution should be faster.
This does not correspond to N = 3. 3x3 blocks do not work. But expanding the array to 6d (as Divakar does) and changing some axes, we put the subunits in the correct order.
For N=3 :
In [57]: block=np.bmat([[A,D],[C,B]]) In [58]: b1=block.A.reshape(2,3,3,2,3,3) In [59]: b2=b1.transpose(1,0,2,4,3,5) In [60]: b3=b2.reshape(18,18) In [61]: np.allclose(b3,final) Out[61]: True
In tests with fast times (N = 3), my approach is about half the slicing_app speed.
As a curiosity, bmat works with string input: np.bmat('A,D;C,B') . This is because np.matrix tried many years ago to give a MATLAB feel.