86

I tried the following:

>>> a = np.array([1,2,3])
>>> b = np.array([4,5,6])
>>> np.concatenate((a,b), axis=0)
array([1, 2, 3, 4, 5, 6])
>>> np.concatenate((a,b), axis=1)
array([1, 2, 3, 4, 5, 6])

However, I'd expect at least that one result looks like this

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

Why is it not concatenated vertically?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
toom
  • 12,864
  • 27
  • 89
  • 128
  • 8
    weird !!! You can use `np.vstack((a,b))` for this purpose (in case you don't know it) – Abid Rahman K Feb 19 '14 at 17:42
  • 2
    Guys, sorry for the stupid comment, but why do you use brackets twice in case of vstack? – Dmitry Isakov Aug 11 '20 at 18:05
  • 3
    @DmitryIsakov Don't worry, it's not a stupid comment. numpy does this because the one required argument when using `vstack` is a tuple. In other words, `np.vstack((a,b))` is the same as doing `np.vstack(tup=(a,b))`. See here: https://numpy.org/doc/stable/reference/generated/numpy.vstack.html – Ian Sep 25 '20 at 16:15
  • 1
    @DmitryIsakov assuming of course that you were asking about parentheses `( )` and not square brackets `[ ]` – Ian Sep 25 '20 at 16:23

4 Answers4

112

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,:]))
gg349
  • 21,996
  • 5
  • 54
  • 64
34

If the actual problem at hand is to concatenate two 1-D arrays vertically, and we are not fixated on using concatenate to perform this operation, I would suggest the use of np.column_stack:

In []: a = np.array([1,2,3])
In []: b = np.array([4,5,6])
In []: np.column_stack((a, b))
array([[1, 4],
       [2, 5],
       [3, 6]])
Kshitij Saraogi
  • 6,821
  • 8
  • 41
  • 71
11

A not well known feature of numpy is to use r_. This is a simple way to build up arrays quickly:

import numpy as np
a = np.array([1,2,3])
b = np.array([4,5,6])
c = np.r_[a[None,:],b[None,:]]
print(c)
#[[1 2 3]
# [4 5 6]]

The purpose of a[None,:] is to add an axis to array a.

bougui
  • 3,507
  • 4
  • 22
  • 27
6
a = np.array([1,2,3])
b = np.array([4,5,6])
np.array((a,b))

works just as well as

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

Regardless of whether it is a list of lists or a list of 1d arrays, np.array tries to create a 2d array.

But it's also a good idea to understand how np.concatenate and its family of stack functions work. In this context concatenate needs a list of 2d arrays (or any anything that np.array will turn into a 2d array) as inputs.

np.vstack first loops though the inputs making sure they are at least 2d, then does concatenate. Functionally it's the same as expanding the dimensions of the arrays yourself.

np.stack is a new function that joins the arrays on a new dimension. Default behaves just like np.array.

Look at the code for these functions. If written in Python you can learn quite a bit. For vstack:

return _nx.concatenate([atleast_2d(_m) for _m in tup], 0)
hpaulj
  • 221,503
  • 14
  • 230
  • 353