[python] Most efficient way to reverse a numpy array

Believe it or not, after profiling my current code, the repetitive operation of numpy array reversion ate a giant chunk of the running time. What I have right now is the common view-based method:

reversed_arr = arr[::-1]

Is there any other way to do it more efficiently, or is it just an illusion from my obsession with unrealistic numpy performance?

This question is related to python numpy

The answer is


np.fliplr() flips the array left to right.

Note that for 1d arrays, you need to trick it a bit:

arr1d = np.array(some_sequence)
reversed_arr = np.fliplr([arr1d])[0]

Expanding on what others have said I will give a short example.

If you have a 1D array ...

>>> import numpy as np
>>> x = np.arange(4) # array([0, 1, 2, 3])
>>> x[::-1] # returns a view
Out[1]: 
array([3, 2, 1, 0])

But if you are working with a 2D array ...

>>> x = np.arange(10).reshape(2, 5)
>>> x
Out[2]:
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])

>>> x[::-1] # returns a view:
Out[3]: array([[5, 6, 7, 8, 9],
               [0, 1, 2, 3, 4]])

This does not actually reverse the Matrix.

Should use np.flip to actually reverse the elements

>>> np.flip(x)
Out[4]: array([[9, 8, 7, 6, 5],
               [4, 3, 2, 1, 0]])

If you want to print the elements of a matrix one-by-one use flat along with flip

>>> for el in np.flip(x).flat:
>>>     print(el, end = ' ')
9 8 7 6 5 4 3 2 1 0

In order to have it working with negative numbers and a long list you can do the following:

b = numpy.flipud(numpy.array(a.split(),float))

Where flipud is for 1d arra


As mentioned above, a[::-1] really only creates a view, so it's a constant-time operation (and as such doesn't take longer as the array grows). If you need the array to be contiguous (for example because you're performing many vector operations with it), ascontiguousarray is about as fast as flipud/fliplr:

enter image description here


Code to generate the plot:

import numpy
import perfplot


perfplot.show(
    setup=lambda n: numpy.random.randint(0, 1000, n),
    kernels=[
        lambda a: a[::-1],
        lambda a: numpy.ascontiguousarray(a[::-1]),
        lambda a: numpy.fliplr([a])[0],
    ],
    labels=["a[::-1]", "ascontiguousarray(a[::-1])", "fliplr"],
    n_range=[2 ** k for k in range(25)],
    xlabel="len(a)",
)

Because this seems to not be marked as answered yet... The Answer of Thomas Arildsen should be the proper one: just use

np.flipud(your_array) 

if it is a 1d array (column array).

With matrizes do

fliplr(matrix)

if you want to reverse rows and flipud(matrix) if you want to flip columns. No need for making your 1d column array a 2dimensional row array (matrix with one None layer) and then flipping it.


I will expand on the earlier answer about np.fliplr(). Here is some code that demonstrates constructing a 1d array, transforming it into a 2d array, flipping it, then converting back into a 1d array. time.clock() will be used to keep time, which is presented in terms of seconds.

import time
import numpy as np

start = time.clock()
x = np.array(range(3))
#transform to 2d
x = np.atleast_2d(x)
#flip array
x = np.fliplr(x)
#take first (and only) element
x = x[0]
#print x
end = time.clock()
print end-start

With print statement uncommented:

[2 1 0]
0.00203907123594

With print statement commented out:

5.59799927506e-05

So, in terms of efficiency, I think that's decent. For those of you that love to do it in one line, here is that form.

np.fliplr(np.atleast_2d(np.array(range(3))))[0]