首页 文章

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

提问于
浏览
221

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

reversed_arr = arr[::-1]

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

6 回答

  • 187

    创建 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中做事的最快方法 . 如果这是你已经在做的事情,我认为你不能改进它 .

    附:在这里讨论numpy的观点:

    View onto a numpy array?

  • 0

    np.fliplr() 从左到右翻转阵列 .

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

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

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

    np.flipud(your_array)
    

    如果它是1d数组(列数组) .

    用matrizes做

    fliplr(matrix)
    

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

  • 27

    如上所述, a[::-1] 实际上只创建一个视图,因此随着数组的增长,它需要更长的时间 . 如果你需要数组是连续的(例如因为你用它执行了很多向量运算), ascontiguousarrayflipup / 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,
        )
    
  • 37

    我将扩展关于 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]
    
  • 3

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

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

    flipud适用于1d arra

相关问题