Concatenate Two Numpy Arrays Vertically

Concatenate two NumPy arrays vertically

Because both a and b have only one axis, as their shape is (3), and the axis parameter specifically refers to the axis of the elements to concatenate.

this example should clarify what concatenate is doing with axis. Take two vectors with two axis, with shape (2,3):

a = np.array([[1,5,9], [2,6,10]])
b = np.array([[3,7,11], [4,8,12]])

concatenates along the 1st axis (rows of the 1st, then rows of the 2nd):

np.concatenate((a,b), axis=0)
array([[ 1, 5, 9],
[ 2, 6, 10],
[ 3, 7, 11],
[ 4, 8, 12]])

concatenates along the 2nd axis (columns of the 1st, then columns of the 2nd):

np.concatenate((a, b), axis=1)
array([[ 1, 5, 9, 3, 7, 11],
[ 2, 6, 10, 4, 8, 12]])

to obtain the output you presented, you can use vstack

a = np.array([1,2,3])
b = np.array([4,5,6])
np.vstack((a, b))
array([[1, 2, 3],
[4, 5, 6]])

You can still do it with concatenate, but you need to reshape them first:

np.concatenate((a.reshape(1,3), b.reshape(1,3)))
array([[1, 2, 3],
[4, 5, 6]])

Finally, as proposed in the comments, one way to reshape them is to use newaxis:

np.concatenate((a[np.newaxis,:], b[np.newaxis,:]))

Concatenating numpy arrays vertically and horizontally

Here is a way using hstack and vstack:

>>> a  = [[1,2],
... [8,9]]
>>> x = np.array([4, 5, 6])

>>> b = np.vstack((a, x[:-1]))
>>> print np.hstack((b, x[:, None]))
[[1 2 4]
[8 9 5]
[4 5 6]]

You can combine this into one line:

>>> print np.hstack((np.vstack((a, x[:-1])), x[:, None]))
[[1 2 4]
[8 9 5]
[4 5 6]]

How to vertically concatenate two arrays in Python?

The problem is that both a and b are 1D arrays and so there's only one axis to join them on.

Instead, you can use vstack (v for vertical):

>>> np.vstack((a,b))
array([[1, 2, 3, 4],
[5, 6, 7, 8]])

Also, row_stack is an alias of the vstack function:

>>> np.row_stack((a,b))
array([[1, 2, 3, 4],
[5, 6, 7, 8]])

It's also worth noting that multiple arrays of the same length can be stacked at once. For instance, np.vstack((a,b,x,y)) would have four rows.

Under the hood, vstack works by making sure that each array has at least two dimensions (using atleast_2D) and then calling concatenate to join these arrays on the first axis (axis=0).

Concatenating/Appending Multiple Vertical Arrays of Different Sizes

First, vstack on an array treats the array as a list on the first dimension. It then makes each 'row/element' into a 2d array, and concatenates them.

These all do the same thing:

In [94]: np.vstack(np.array([1,2,3]))                                           
Out[94]:
array([[1],
[2],
[3]])
In [95]: np.vstack([[1],[2],[3]])
Out[95]:
array([[1],
[2],
[3]])
In [96]: np.concatenate(([[1]],[[2]],[[3]]), axis=0)
Out[96]:
array([[1],
[2],
[3]])

Matching arrays or lists can be 'column_stack` - the arrays are turned into (n,1) arrays, and then joined on the 2nd dimension:

In [97]: np.column_stack(([1,2,3], [4,5,6]))                                    
Out[97]:
array([[1, 4],
[2, 5],
[3, 6]])

But the ragged arrays don't work.

An array of lists/arrays of differing size has object dtype, and is, for many purposes like a list of lists:

In [98]: np.array(([1,2,3],[4,5,6,7]))                                          
Out[98]: array([list([1, 2, 3]), list([4, 5, 6, 7])], dtype=object)

Your last structure could written as a ragged list of lists:

In [100]: [[1,2,5,6,10,11],[2,3,6,7,11,12],[3,4,7,8,12,13],[8,9]]               
Out[100]: [[1, 2, 5, 6, 10, 11], [2, 3, 6, 7, 11, 12], [3, 4, 7, 8, 12, 13], [8, 9]]
In [101]: np.array(_)
Out[101]:
array([list([1, 2, 5, 6, 10, 11]), list([2, 3, 6, 7, 11, 12]),
list([3, 4, 7, 8, 12, 13]), list([8, 9])], dtype=object)

Notice though this doesn't line up the [8,9] with the others. You need some sort of filler/spacer. The Python list zip_longest provides that:

In [102]: from itertools import zip_longest                                     
In [103]: alist = [[1,2,3],[2,3,4],[5,6,7,8],[11,12,13]]
In [104]: list(zip_longest(*alist))
Out[104]: [(1, 2, 5, 11), (2, 3, 6, 12), (3, 4, 7, 13), (None, None, 8, None)]

With this padding we can make a 2d array (object dtype because of the None):

In [105]: np.array(_)                                                           
Out[105]:
array([[1, 2, 5, 11],
[2, 3, 6, 12],
[3, 4, 7, 13],
[None, None, 8, None]], dtype=object)

===

I can generate the numbers in your last display with a little function:

In [232]: def foo(i,n): 
...: return np.column_stack((np.arange(i,i+n), np.arange(i+1,i+1+n)))
...:
In [233]: foo(1,3)
Out[233]:
array([[1, 2],
[2, 3],
[3, 4]])
In [234]: foo(5,4)
Out[234]:
array([[5, 6],
[6, 7],
[7, 8],
[8, 9]])
In [235]: foo(10,3)
Out[235]:
array([[10, 11],
[11, 12],
[12, 13]])

I can put all those arrays in a list:

In [236]: [Out[233], Out[234], Out[235]]                                        
Out[236]:
[array([[1, 2],
[2, 3],
[3, 4]]), array([[5, 6],
[6, 7],
[7, 8],
[8, 9]]), array([[10, 11],
[11, 12],
[12, 13]])]

I can turn that list into an object dtype array:

In [237]: np.array([Out[233], Out[234], Out[235]])                              
Out[237]:
array([array([[1, 2],
[2, 3],
[3, 4]]),
array([[5, 6],
[6, 7],
[7, 8],
[8, 9]]),
array([[10, 11],
[11, 12],
[12, 13]])], dtype=object)

I could also display several rows of these arrays with:

In [238]: for i in range(3): 
...: print(np.hstack([a[i,:] for a in Out[236]]))
...:
[ 1 2 5 6 10 11]
[ 2 3 6 7 11 12]
[ 3 4 7 8 12 13]

but to show the 4th row, which only exists for the middle array, I'd have to add more code to test whether we're off the end, and whether to add padding etc. I'll leave that exercise up to you, if it really matters. :)

Efficient way to concatenate multiple numpy arrays

Use np.tile

Code

np.tile(np.array([1, 1]), (10, 1))
# Output: Same as OP
array([[1, 1],
[1, 1],
[1, 1],
[1, 1],
[1, 1],
[1, 1],
[1, 1],
[1, 1],
[1, 1],
[1, 1]])

Explanation

Function np.tile

Usage: np.tile(A, reps)

parameter A

Object which acts as a “tile” that gets copied and repeated

  • Numpy array
  • Python list
  • Python tuple

parameter reps

Indicates how to repeat the input array if reps is an integer then A is
repeated n times, horizontally. If reps is a tuple (e.g. (r, c))

  • r is the number of repeats downwards and
  • c is the number of repeats across.

Adding Different Arrays Vertically

Using vstack

arr1 = np.array([1, 1])
arr2 = np.array([2, 2])
arr3 = np.array([3, 3])
arr = [arr1, arr2, arr3]
np.vstack(arr)

# Output
array([[1, 1],
[2, 2],
[3, 3]])

Concatenating two one-dimensional NumPy arrays

Use:

np.concatenate([a, b])

The arrays you want to concatenate need to be passed in as a sequence, not as separate arguments.

From the NumPy documentation:

numpy.concatenate((a1, a2, ...), axis=0)

Join a sequence of arrays together.

It was trying to interpret your b as the axis parameter, which is why it complained it couldn't convert it into a scalar.

How can I vertically concatenate 1x2 arrays in numpy?

Setting a shape on A allows concatenation of similar column sized arrays:

import numpy as np
A = np.array([])
A.shape=(0,2) # set A to be 0 rows x 2 cols matrix
for i in range(5):
xa = np.array([[i, i+1]])
A = np.concatenate( (A,xa) )
print A

output
[[ 0. 1.]
[ 1. 2.]
[ 2. 3.]
[ 3. 4.]
[ 4. 5.]]

without A.shape = (0,2) an Exception will be thrown:

Traceback (most recent call last):
File "./arr.py", line 5, in <module>
A = np.concatenate( (A,xa) )
ValueError: all the input arrays must have same number of dimensions

Concatenating 2 dimensional numpy arrays in Python

You can use hstack and vector broadcasting for that:

a = np.array([[1,2,3],[3,4,5],[6,7,8]])  
b = np.array([9,10,11])
res = np.hstack((a, b[:,None]))
print(res)

Output:

[[ 1  2  3  9]
[ 3 4 5 10]
[ 6 7 8 11]]

Note that you cannot use concatenate because the array have different shapes. hstack stack horizontally the multi-dimentional arrays so it just add a new line at the end here. A broadcast operation (b[:,None]) is needed so that the appended vector is a vertical one.



Related Topics



Leave a reply



Submit