Reputation: 5191
I have a loop over 2-dimensional np.arrays() and I need to add these arrays to one single array.
in plain Python I would do this
In [37]: a1 = [[1,2],[3,4]]
In [38]: b1 = [[5,6],[7,8]]
In [39]: l1 = []
In [40]: l1.append(a1)
In [41]: l1.append(b1)
In [42]: l1
Out[42]: [[[1, 2], [3, 4]], [[5, 6], [7, 8]]]
How do I get the same result with numpy for l1?
Upvotes: 4
Views: 327
Reputation: 176740
Here is one way to produce that output from the arrays:
>>> np.dstack((a1,b1)).transpose(2,0,1)
array([[[ 1, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]],
np.dstack
produces a 3D array, but the axes need to read in a different order. We want the order of the axes (0, 1, 2)
changed to (2, 0, 1)
, hence the need to transpose and swap the axes.
Below is potentially useful - but not immediately relevant - information about concatenating arrays. (Typed before my misinterpretation of the question was pointed out.)
One way to join arrays is to use np.concatenate
:
>>> np.concatenate((a1, b1))
array([[1, 2],
[3, 4],
[5, 6],
[7, 8]])
This stacks one below the other. You can also concatenate the arrays side-by-side with np.concatenate((a1, b1), axis=1)
. (More than two arrays can be passed into the function.)
There are other functions to do this; the two operations above can be done with np.vstack((a1,b1))
and np.hstack((a1,b1))
respectively.
If you want to join in the arrays in a 3D array, you can use np.dstack((a1,b1))
:
array([[[1, 5],
[2, 6]],
[[3, 7],
[4, 8]]])
Keep in mind that Numpy arrays, unlike Python lists, cannot grow in memory dynamically. These operations cause the arrays to be copied and a new block of memory to be filled with the bigger array. This can be inefficient if the arrays are large.
Upvotes: 3
Reputation: 22671
Just use:
l1 = np.array([a1,b1])
Notice also that in numpy
you don't append to arrays. You allocate them first, and then you fill them:
import numpy as np
a1 = np.array([[1,2],[3,4]])
b1 = np.array([[5,6],[7,8]])
#allocate exact size of the final array
l1 = empty(((2,)+a1.shape),dtype=a1.dtype)
l1[0]=a1
l1[1]=b1
or you use one of the many helper functions (dstack
,hstack
,concatenate
described by the others)
EDIT: I find both solutions above very readable and close to python lists syntax, but this is rather subjective. Timing how fast this is, you find that both solutions are marginally faster to the fastest solution proposed by @unutbu, based on concatenate. Notice moreover that this does not create a view.
Upvotes: 4
Reputation: 879123
a1 = np.array([[1,2],[3,4]])
b1 = np.array([[5,6],[7,8]])
l1 = np.r_['0,3', a1, b1]
yields
array([[[1, 2],
[3, 4]],
[[5, 6],
[7, 8]]])
The special directive '0,3'
tells np.r_
to concatenate along axis=0
, and produce a result with at least 3 dimensions.
Or, alternatively, using concatenate
and reshape
is more readable and faster:
l1 = np.concatenate([a1, b1]).reshape((2,)+a1.shape))
In [111]: a2 = np.tile(a1, (10000,1))
In [112]: b2 = np.tile(b1, (10000,1))
In [113]: %timeit np.r_['0,3', a2, b2].shape
10000 loops, best of 3: 62.4 µs per loop
In [114]: %timeit np.concatenate([a2, b2]).reshape((2,)+a2.shape)
10000 loops, best of 3: 39.8 µs per loop
Upvotes: 3