反转numpy数组的最有效方法

367 投票
8 回答
589353 浏览
提问于 2025-04-16 21:58

信不信由你,经过对我当前代码的分析,我发现反转numpy数组这个重复操作占用了很大一部分运行时间。我现在使用的是一种常见的基于视图的方法:

reversed_arr = arr[::-1]

有没有其他更高效的方法,还是说这只是我对numpy性能不切实际的执念所产生的错觉呢?

8 个回答

49

因为这个问题似乎还没有被标记为已回答……Thomas Arildsen的回答应该是正确的:只需使用

np.flipud(your_array) 

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

对于矩阵,使用

fliplr(matrix)

如果你想反转行,可以用这个;如果你想翻转列,可以用flipud(matrix)。不需要把你的一维列数组变成一个二维行数组(就是加一层None的矩阵),然后再去翻转它。

91
a[::-1]

这个操作只是创建了一个视图,所以它的执行时间是固定的(也就是说,数组变大了也不会花更多时间)。如果你需要数组是连续的(比如因为你要进行很多向量运算),那么使用 ascontiguousarray 的速度和 flipud/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)",
)
324
reversed_arr = arr[::-1]

这个操作会让你得到一个原始数组 arr 的反向视图。也就是说,如果你对原始数组 arr 做了什么修改,这些修改会立刻在 reversed_arr 中显示出来。因为 arrreversed_arr 共享底层的数据,所以创建这个视图是非常快速的,不需要额外的内存分配或者复制数组的内容。

你可以看看关于 NumPy 视图的讨论:如何创建 NumPy 数组的视图?


关于视图性能问题的可能解决方案

你是不是比需要的更频繁地重新创建视图?你应该可以这样做:

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 的专家,但这看起来是用 NumPy 做事情最快的方法。如果你已经在这样做,我觉得你就没有更好的方法了。

撰写回答