反转numpy数组的最有效方法
信不信由你,经过对我当前代码的分析,我发现反转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
差不多快:
生成这个图的代码:
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
中显示出来。因为 arr
和 reversed_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 做事情最快的方法。如果你已经在这样做,我觉得你就没有更好的方法了。