最有效的方法来反转numpy数组

时间:2011-07-21 04:58:24

标签: python numpy

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

reversed_arr = arr[::-1]

有没有其他方法可以更有效地做到这一点,还是仅仅因为我对不切实际的笨拙表现的迷恋而产生错觉?

8 个答案:

答案 0 :(得分:202)

创建reversed_arr时,您正在创建原始数组的视图。然后,您可以更改原始数组,视图将更新以反映更改。

您是否更频繁地重新创建视图?你应该可以这样做:

arr = np.array(some_sequence)
reversed_arr = arr[::-1]

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

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

P.S。这里对numpy观点进行了很好的讨论:

View onto a numpy array?

答案 1 :(得分:40)

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

enter image description here

生成情节的代码:

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,
    )

答案 2 :(得分:37)

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

请注意,对于1d数组,您需要稍微欺骗它:

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

答案 3 :(得分:34)

因为这似乎没有被标记为已回答...... Thomas Arildsen的答案应该是正确的:只需使用

np.flipud(your_array) 

如果是1d数组(列数组)。

用matrizes做

fliplr(matrix)

如果要反转行,请flipud(matrix)如果要翻转列。无需将1d列数组设为2维行数组(带有一个无图层的矩阵),然后将其翻转。

答案 4 :(得分:3)

我将扩展前面关于np.fliplr()的答案。下面是一些代码,演示了如何构建1d数组,将其转换为2d数组,翻转它,然后转换回1d数组。 time.clock()将用于保留时间,以秒为单位。

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语句:

[2 1 0]
0.00203907123594

将print语句注释掉:

5.59799927506e-05

因此,就效率而言,我认为这是不错的。对于那些喜欢一行代表的人来说,就是这种形式。

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

答案 5 :(得分:0)

在其他人说的内容上做一个扩展,我将举一个简短的例子。

如果您有一维数组...

>>> 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])

但是,如果您正在使用2D阵列...

>>> 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实际反转元素

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

如果您要一张一张地打印矩阵的元素,请同时使用平面和翻转

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

答案 6 :(得分:0)

基于切片符号的 np.flip 模拟为 [::-1,::-1]

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

out: [[1. 2.]
      [3. 4.]
      [5. 6.]]

b=a[::-1,::-1]
print(b)

out: [[1. 2.]
      [3. 4.]
      [5. 6.]]

答案 7 :(得分:-1)

为了让它使用负数和长列表,您可以执行以下操作:

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

其中flipud是1d arra