399

How do I concatenate two one-dimensional arrays in NumPy? I tried numpy.concatenate:

import numpy as np
a = np.array([1, 2, 3])
b = np.array([4, 5])
np.concatenate(a, b)

But I get an error:

TypeError: only length-1 arrays can be converted to Python scalars

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
highBandWidth
  • 16,751
  • 20
  • 84
  • 131
  • 7
    If you want to concatenate them (into a single array) **along** an axis, use `np.concatenat(..., axis)`. If you want to stack them vertically, use `np.vstack`. If you want to stack them (into multiple arrays) horizontally, use `np.hstack`. (If you want to stack them depth-wise, i.e. teh 3rd dimension, use `np.dstack`). Note that the latter are similar to pandas `pd.concat` – smci Apr 29 '20 at 02:52

7 Answers7

530

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.

Mateen Ulhaq
  • 24,552
  • 19
  • 101
  • 135
Winston Ewert
  • 44,070
  • 10
  • 68
  • 83
  • 3
    thanks! just curious - what is the logic behind this? – user391339 Jul 12 '16 at 06:08
  • 9
    @user391339, what if you wanted to concatenate three arrays? The function is more useful in taking a sequence then if it just took two arrays. – Winston Ewert Jul 12 '16 at 17:13
  • @WinstonEwert Assuming the issue isn't that it's hardcoded to two arguments, you could use it like `numpy.concatenate(a1, a2, a3)` or `numpy.concatenate(*[a1, a2, a3])` if you prefer. Python's fluid enough that the difference ends up feeling more cosmetic than substantial, but it's good when the API is consistent (e.g. if all the numpy functions that take variable length argument lists require explicit sequences). – Jim K. Aug 24 '16 at 20:43
  • 1
    @JimK. What would happen to the axis parameter? – Winston Ewert Aug 24 '16 at 21:12
  • 1
    Assuming the things to concatenate are all positional parameters, you could keep axis as a keyword argument e.g. `def concatx(*sequences, **kwargs)`). It's not ideal since you can't seem to name the keyword args explicitly in the signature this way, but there are workarounds. – Jim K. Aug 24 '16 at 23:07
  • `np.concatentate` is a `Type: builtin_function_or_method`. So the interface is 'hard coded' in `numpy` compiled code. `np.append` is a poorly conceived alternative that takes 2 arguments (plus keywords) and puts them in a sequence. The whole range of `stack` functions also work as `concatenate` does. So does the ubiquitous `np.array`. As does the basic Python `list()`. – hpaulj Mar 24 '17 at 01:12
82

There are several possibilities for concatenating 1D arrays, e.g.,

import numpy as np

np.r_[a, a]
np.stack([a, a]).reshape(-1)
np.hstack([a, a])
np.concatenate([a, a])

All those options are equally fast for large arrays; for small ones, concatenate has a slight edge:

enter image description here

The plot was created with perfplot:

import numpy
import perfplot

perfplot.show(
    setup=lambda n: numpy.random.rand(n),
    kernels=[
        lambda a: numpy.r_[a, a],
        lambda a: numpy.stack([a, a]).reshape(-1),
        lambda a: numpy.hstack([a, a]),
        lambda a: numpy.concatenate([a, a]),
    ],
    labels=["r_", "stack+reshape", "hstack", "concatenate"],
    n_range=[2 ** k for k in range(19)],
    xlabel="len(a)",
)
Nico Schlömer
  • 53,797
  • 27
  • 201
  • 249
  • 18
    The alternatives all use `np.concatenate`. They just massage the input list in various ways before hand. `np.stack` for example adds an extra dimension to all input arrays. Look at their source code. Only `concatenate` is compiled. – hpaulj May 26 '17 at 16:45
  • 2
    Just to add to @hpaulj 's comment - the times all converge as the size of the arrays grows because the `np.concatenate` makes copies of the inputs. This memory and time cost then outweighs the time spent 'massaging' the input. – n1k31t4 Mar 09 '18 at 18:29
  • thanks! I used you code to check also the influence of the number of arrays (of size 100) and got similar results: https://i.stack.imgur.com/w6ojK.png – Ofir Shifman Apr 19 '22 at 11:00
  • I didn't know about perfplot, really handy. – Tacio Medeiros Jun 03 '23 at 16:22
39

The first parameter to concatenate should itself be a sequence of arrays to concatenate:

numpy.concatenate((a,b)) # Note the extra parentheses.
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Gabe
  • 84,912
  • 12
  • 139
  • 238
14

An alternative ist to use the short form of "concatenate" which is either "r_[...]" or "c_[...]" as shown in the example code beneath (see Link for additional information):

%pylab
vector_a = r_[0.:10.] #short form of "arange"
vector_b = array([1,1,1,1])
vector_c = r_[vector_a,vector_b]
print vector_a
print vector_b
print vector_c, '\n\n'

a = ones((3,4))*4
print a, '\n'
c = array([1,1,1])
b = c_[a,c]
print b, '\n\n'

a = ones((4,3))*4
print a, '\n'
c = array([[1,1,1]])
b = r_[a,c]
print b

print type(vector_b)

Which results in:

[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.]
[1 1 1 1]
[ 0.  1.  2.  3.  4.  5.  6.  7.  8.  9.  1.  1.  1.  1.] 


[[ 4.  4.  4.  4.]
 [ 4.  4.  4.  4.]
 [ 4.  4.  4.  4.]] 

[[ 4.  4.  4.  4.  1.]
 [ 4.  4.  4.  4.  1.]
 [ 4.  4.  4.  4.  1.]] 


[[ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 4.  4.  4.]] 

[[ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 4.  4.  4.]
 [ 1.  1.  1.]]
Glorfindel
  • 21,988
  • 13
  • 81
  • 109
Semjon Mössinger
  • 1,798
  • 3
  • 22
  • 32
4

Some more facts from the numpy docs :

With syntax as numpy.concatenate((a1, a2, ...), axis=0, out=None)

axis = 0 for row-wise concatenation axis = 1 for column-wise concatenation

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

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

# Appending after last column
>>> np.concatenate((a, b.T), axis=1)    # Notice the transpose
array([[1, 2, 5],
       [3, 4, 6]])

# Flattening the final array
>>> np.concatenate((a, b), axis=None)
array([1, 2, 3, 4, 5, 6])

I hope it helps !

Pe Dro
  • 2,651
  • 3
  • 24
  • 44
2

Here are more approaches for doing this by using numpy.ravel(), numpy.array(), utilizing the fact that 1D arrays can be unpacked into plain elements:

# we'll utilize the concept of unpacking
In [15]: (*a, *b)
Out[15]: (1, 2, 3, 5, 6)

# using `numpy.ravel()`
In [14]: np.ravel((*a, *b))
Out[14]: array([1, 2, 3, 5, 6])

# wrap the unpacked elements in `numpy.array()`
In [16]: np.array((*a, *b))
Out[16]: array([1, 2, 3, 5, 6])
kmario23
  • 57,311
  • 13
  • 161
  • 150
0

Slightly different problem, that is if you want two 1D array with shape (n,) into (2,n), then you have the following options:

import numpy as np

np.r_[[a], [a]]
np.stack([a, a])
np.vstack([a, a])
np.concatenate([[a], [a]])
np.array([a, a])

The fastest way is to use plain numpy.array:

import numpy
import perfplot

perfplot.show(
    setup=lambda n: numpy.random.rand(n),
    kernels=[
        lambda a: numpy.r_[[a], [a]],
        lambda a: numpy.stack([a, a]),
        lambda a: numpy.vstack([a, a]),
        lambda a: numpy.concatenate([[a], [a]]),
        lambda a: numpy.array([a, a]),
    ],
    labels=["r_", "stack", "vstack", "concatenate", "array"],
    n_range=[2 ** k for k in range(19)],
    xlabel="len(a)",
)

enter image description here

Muhammad Yasirroni
  • 1,512
  • 12
  • 22