How the NumPy append operation works

Ben Cook • Posted 2021-10-06 • Last updated 2021-10-15

Anyone familiar with Python will know about the list append method:

a = [1, 2, 3]
a.append(4)

print(a)

# Expected result
# [1, 2, 3, 4]

But what if you want to append to a NumPy array? In that case, you have a couple options. The most common thing you’ll see in idiomatic NumPy code is the np.concatenate() operation which concatenates two or more arrays along a given axis.

NumPy does have an np.append() operation that you can use instead, but you have to be a little careful because the API has a some weirdness in it.

For 1-D arrays, np.append() works as you might expect (the same as Python lists):

np.append(np.zeros(3), 1)

# Expected result
# array([0., 0., 0., 1.])

You don’t get .append() as a method on an ndarray but you can stick a single value onto the end of a vector. Where it becomes weird is when you try to append N-D arrays.

Check this out. Let’s start with a 3×3 identity matrix both Python and NumPy:

x = np.eye(3)
print(x)

# Expected result
# [[1. 0. 0.]
#  [0. 1. 0.]
#  [0. 0. 1.]]

python_x = x.astype(int).tolist()
print(python_x)

# Expected result
# [[1, 0, 0], [0, 1, 0], [0, 0, 1]]

So far so good. There are differences in how the arrays get printed to the screen and the underlying data type of the values, but basically x and python_x have the same data.

Now append the same data to each of them:

python_x.append([1, 0, 0])
print(python_x)

# Expected result
# [[1, 0, 0], [0, 1, 0], [0, 0, 1], [1, 0, 0]]

np.append(x, [1, 0, 0])

# Expected result
# array([1., 0., 0., 0., 1., 0., 0., 0., 1., 1., 0., 0.])

Notice: Python list append adds a row to the matrix, whereas NumPy flattens the original array and appends a flattened array to it, leaving us with an array that has a different rank than the inputs.

This behavior is clearly laid out in the np.append() documentation, but it’s strange if you’re expecting the standard Python approach to work. If you want to append a row to a 2D array in NumPy, you need to 1) make sure the appended value has the same number of dimensions and 2) specify the axis:

np.append(x, [[1, 0, 0]], axis=0)

# Expected result
# array([[1., 0., 0.],
#        [0., 1., 0.],
#        [0., 0., 1.],
#        [1., 0., 0.]])

Or you can just use np.concatenate() like everybody else:

np.concatenate([x, [[1, 0, 0]]])

# Expected result
# array([[1., 0., 0.],
#        [0., 1., 0.],
#        [0., 0., 1.],
#        [1., 0., 0.]])

You still have to match the number of dimensions in all inputs, but the behavior is less likely to surprise future readers of your code.