关于python:最有效的方法来反转numpy数组

Most efficient way to reverse a numpy array

信不信由你,在分析了我当前的代码之后,numpy数组反转的重复操作占用了大量的运行时间。我现在拥有的是基于视图的通用方法:

1
reversed_arr = arr[::-1]

有没有其他方法可以更有效地做到这一点,或者这只是我对不切实际的麻木表现的痴迷造成的幻觉?


创建reversed_arr时,将在原始数组中创建一个视图。然后可以更改原始数组,视图将更新以反映更改。

创建视图的频率是否比需要的频率高?您应该能够这样做:

1
2
3
4
5
6
7
arr = np.array(some_sequence)
reversed_arr = arr[::-1]

do_something(arr)
look_at(reversed_arr)
do_something_else(arr)
look_at(reversed_arr)

我不是一个麻木的专家,但这似乎是在麻木中做事情的最快方式。如果这是你已经在做的,我认为你不能改进它。

P.S.关于麻木观点的伟大讨论:

查看一个麻木的数组?


如前所述,a[::-1]实际上只创建一个视图,因此它是一个持续时间操作(因此不会随着数组的增长而花费更长的时间)。如果需要数组是连续的(例如,因为使用它执行了许多向量运算),那么ascontiguousarray的速度大约与flipupfliplr的速度一样快:

enter image description here

生成绘图的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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)',
    logx=True,
    logy=True,
    )


np.fliplr()将数组从左向右翻转。

请注意,对于一维数组,需要稍微欺骗一下:

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


因为这似乎还没有被标记为回答…托马斯·阿里森的回答应该是正确的:只用

1
np.flipud(your_array)

如果是一维数组(列数组)。

有母校吗?

1
fliplr(matrix)

如果要反转行,则返回flipud(matrix),如果要翻转列。无需使一维列数组成为二维行数组(具有一个无层的矩阵),然后翻转它。


我将进一步讨论前面关于np.fliplr()的回答。下面是一些代码,演示如何构造一维数组,将其转换为二维数组,翻转它,然后再转换回一维数组。time.clock()将用于保持时间,以秒表示。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
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

未注释print语句:

1
2
[2 1 0]
0.00203907123594

打印语句被注释掉:

1
5.59799927506e-05

所以,在效率方面,我认为这是很好的。对于那些喜欢用一条线来做这件事的人来说,这就是那个形式。

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


扩展别人所说的,我将举一个简短的例子。

如果你有一个一维数组…

1
2
3
4
5
>>> 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])

但是如果你使用的是二维数组…

1
2
3
4
5
6
7
8
9
>>> 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]])

这实际上并没有颠倒矩阵。

应该使用np.flip来实际反转元素

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

如果要逐个打印矩阵的元素,请使用"平"和"翻转"

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


要使其与负数和长列表一起工作,可以执行以下操作:

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

Flipud用于1d阵列