TAGS :Viewed: 4 - Published at: a few seconds ago

[ Double loops for "concatenation of subarrays in bigger array" ]

I want to assemble several subarrays in a big array automaticly, "manually" it s that :

import numpy as np
blank = np.empty([4,4])


A = np.ones([2,2])
B = np.ones([2,2]) * 2
C = np.ones([2,2]) * 3
D = np.ones([2,2]) * 4


A3d = np.reshape(A,(1,A.shape[0],A.shape[1]))
B3d = np.reshape(B,(1,B.shape[0],B.shape[1]))
C3d = np.reshape(C,(1,C.shape[0],C.shape[1]))
D3d = np.reshape(D,(1,D.shape[0],D.shape[1]))


conc = np.concatenate((A3d,B3d,C3d,D3d), axis=0)

blank[0:2,0:2] = conc[0,:,:]
blank[0:2,2:4] = conc[1,:,:]
blank[2:4,0:2] = conc[2,:,:]
blank[2:4,2:4] = conc[3,:,:]

I try with a double loop for but it doesn t work...

blank = np.empty([4,4])

for j in range(blank.shape[0]/A.shape[0]):
    for i in range(blank.shape[0]/A.shape[0]):
            blank[0:A.shape[0],j*A.shape[0]:A.shape[0]*(j+1)] = conc[j,:,:]

Answer 1


A shorter way of making conc

conc = np.array([A,B,C,D])

you could concatenate the pieces in 2 steps to make blank directly

blank = np.vstack([np.hstack([A,B]),np.hstack([C,D])])

Is that still 'manual'?

Lets step back and look at blank:

In [65]: blank
Out[65]: 
array([[ 1.,  1.,  2.,  2.],
       [ 1.,  1.,  2.,  2.],
       [ 3.,  3.,  4.,  4.],
       [ 3.,  3.,  4.,  4.]])

In [66]: blank.flatten()
Out[66]: 
array([ 1.,  1.,  2.,  2.,  1.,  1.,  2.,  2.,  3.,  3.,  4.,  4.,  3.,
        3.,  4.,  4.])

Often it is possible to assemble a large array of one concat followed by a reshape. But

In [69]: conc.flatten()
Out[69]: 
array([ 1.,  1.,  1.,  1.,  2.,  2.,  2.,  2.,  3.,  3.,  3.,  3.,  4.,
        4.,  4.,  4.])

The data elements in conc are contiguous. Those in blank are interspersed. That's what makes constructing blank trickier.

Do the elements have to be arranged as in blank? Why not?

In [82]: conc.reshape(4,4)
Out[82]: 
array([[ 1.,  1.,  1.,  1.],
       [ 2.,  2.,  2.,  2.],
       [ 3.,  3.,  3.,  3.],
       [ 4.,  4.,  4.,  4.]])

But to focus on the double iteration, let's try:

In [89]: for i in range(0,4,2):
   ....:     for j in range(0,4,2):
   ....:         print blank[i:i+2, j:j+2]
[[ 1.  1.]
 [ 1.  1.]]
[[ 2.  2.]
 [ 2.  2.]]
[[ 3.  3.]
 [ 3.  3.]]
[[ 4.  4.]
 [ 4.  4.]]

That gives a clue as to how to construct the assignment

In [100]: conc2=conc.reshape(2,2,2,2)
In [101]: x=np.empty([4,4])
In [102]: for i in range(0,4,2):
    for j in range(0,4,2):
        x[i:i+2, j:j+2]=conc2[i/2,j/2]
   .....:         
In [103]: x
Out[103]: 
array([[ 1.,  1.,  2.,  2.],
       [ 1.,  1.,  2.,  2.],
       [ 3.,  3.,  4.,  4.],
       [ 3.,  3.,  4.,  4.]])

This can be cleaned up, but it is a start.


but back the stacking, here's a way with one iteration:

np.vstack([np.hstack(conc[i:i+2,...]) for i in range(0,4,2)])

Generalizing to other shapes:

In [149]: k,l,m,n = 3,4,2,3
In [150]: conc = np.array([np.ones([m,n],dtype=int)*i for i in range(k*l)])
In [151]: np.vstack([np.hstack(conc[i:i+l]) for i in range(0,k*l,l)]).shape
Out[151]: (6, 12)