Stupid420
Stupid420

Reputation: 1419

creating numpy matrix from nested arrays in a list

I have a list as follows.

list=[[np.array([[-3.,  3.,  3.],
         [-3.,  3.,  3.],
         [-3.,  3.,  3.],
         [ 1.,  4.,  2.],
         [-0.,  4., -5.],
         [ 3.,  6., -5.]])],
 [np.array([[-1.,  2., -3.],
         [-1.,  2., -3.],
         [-1.,  2., -3.],  
         [-2.,  2.,  1.],
         [-0.,  4., -0.],
         ])]]

The list contains numpy array. It should be noted that the number of rows in each numpy array is different but the number of columns are same. As in the example, the number if rows in first array is 6 where as in second array it is 5. My goal is to create a numpy matrix or array from the above list such as.

         [-3.,  3.,  3.]
         [-3.,  3.,  3.]
         [-3.,  3.,  3.]
         [ 1.,  4.,  2.]
         [-0.,  4., -5.]
         [ 3.,  6., -5.] 
         [-1.,  2., -3.]                         

         [-1.,  2., -3.]
         [-1.,  2., -3.]
         [-2.,  2.,  1.]
         [-0.,  4., -0.]

Is there any fast an efficient way to do so in python? I have 1000s of these array which I need to convert.

Upvotes: 0

Views: 1911

Answers (2)

Paul Panzer
Paul Panzer

Reputation: 53029

You can use zip or itertools.chain.from_iterable to "unpack" the arrays and then concatenate:

>>> np.concatenate(next(zip(*l)),axis=0)

or

>>> from itertools import chain
>>> np.concatenate([*chain.from_iterable(l)],axis=0)

output in either case

array([[-3.,  3.,  3.],
       [-3.,  3.,  3.],
       [-3.,  3.,  3.],
       [ 1.,  4.,  2.],
       [-0.,  4., -5.],
       [ 3.,  6., -5.],
       [-1.,  2., -3.],
       [-1.,  2., -3.],
       [-1.,  2., -3.],
       [-2.,  2.,  1.],
       [-0.,  4., -0.]])

Both are fast:

>>> timeit(lambda:np.concatenate(next(zip(*l)),axis=0))
1.8132231349591166
>>> timeit(lambda:np.concatenate([*chain.from_iterable(l)],axis=0))
1.730023997137323
>>> timeit(lambda:np.vstack(np.ravel(l)))
7.647858377080411

Upvotes: 2

Andy L.
Andy L.

Reputation: 25239

You need np.ravel the list before np.vstack:

as in your sample:

l =[[np.array([[-3.,  3.,  3.],
         [-3.,  3.,  3.],
         [-3.,  3.,  3.],
         [ 1.,  4.,  2.],
         [-0.,  4., -5.],
         [ 3.,  6., -5.]])],
 [np.array([[-1.,  2., -3.],
         [-1.,  2., -3.],
         [-1.,  2., -3.],  
         [-2.,  2.,  1.],
         [-0.,  4., -0.],
         ])]]

np.vstack(np.ravel(l))

Out[119]:
array([[-3.,  3.,  3.],
       [-3.,  3.,  3.],
       [-3.,  3.,  3.],
       [ 1.,  4.,  2.],
       [-0.,  4., -5.],
       [ 3.,  6., -5.],
       [-1.,  2., -3.],
       [-1.,  2., -3.],
       [-1.,  2., -3.],
       [-2.,  2.,  1.],
       [-0.,  4., -0.]])

Upvotes: 3

Related Questions