python数列翻转 您所在的位置:网站首页 numpy反转向量 python数列翻转

python数列翻转

2023-08-18 19:01| 来源: 网络整理| 查看: 265

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

reversed_arr = arr[::-1]

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

呃。。。arr[::-1]只是返回一个相反的视图。它尽可能快,而且不依赖于数组中的项目数,因为它只会改变步幅。你要反转的是一个麻木的数组吗?

是的,确实,arr是一个麻木的数组。

六羟甲基三聚氰胺六甲醚。。。好吧,在我的笔记本电脑上,不管阵列的长度是多少,都需要670纳秒。如果这是您的瓶颈,您可能需要切换语言…我很肯定你不会找到一个更快的方法来逆转一个麻木的数组。祝你好运,无论如何!

每击670纳秒和我得到的差不多。运行整个函数的总时间约为2~3秒,其中恢复时间约为1/3,即1秒。因为我要运行这个函数数百万次,所以我认为这是一个瓶颈。如果这确实是我能得到的最好的,大概我只能决定和它一起生活。谢谢!

好吧,你一定要在一个循环中运行它吗?在某些情况下,最好是用数百万个项创建一个麻木的数组,然后对整个数组进行操作。即使您正在执行有限差分法或类似的操作,结果取决于前面的结果,有时也可以执行此操作。(有时强调…)无论如何,如果速度是主要目标,Fortran仍然是王者。以东十一〔二〕是你的朋友!用另一种语言编写算法的性能关键部分(特别是在科学计算中)并从Python中调用它通常是值得的。祝你好运!

我刚刚了解了numpy.flipud(),不知道它与arr[::-1]的性能相比如何。

@贝托。因为它是arr[::-1]的包装器,所以速度较慢:github.com/numpy/numpy/blob/master/numpy/lib/twodim ou base.py。搜索def flipud。这个函数实际上有四行长。

谢谢@madpoisical(顺便说一下,在github上,单击行号,然后复制链接以获取:github.com/numpy/numpy/blob/master/numpy/lib/twodim ou base.py‌&8203;l85)

@贝托。如果你希望你的链接能持续几天以上,这不是个好主意。主分支中的行号经常更改。

创建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)

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

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

查看一个麻木的数组?

它是否有助于创建一个切片对象,然后在许多数组中重用它?

实际上,我只是测试了它,没有看到与在循环外部创建的slice对象有任何区别。(哦,等等,速度稍微快一点。可重复43.4 ms,而1000000次循环为44.3 ms)

look_at函数的作用是什么?

@它应该代表查看数据的任何任务。该示例的要点是,在基础数据更改之后,视图reversed_arr仍然可用。将新值写入数组不会使视图无效。实际上,您也可以使用该视图向数组中写入新值。reversed_arr[0] = 99将数组中的最后一个元素设置为99,与arr[-1] = 99相同。

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

logx=True,

logy=True,

)

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

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

arr1d = np.array(some_sequence)

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

reversed_arr = np.flipud(arr1d)似乎直接起作用。

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

np.flipud(your_array)

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

有母校吗?

fliplr(matrix)

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

我将进一步讨论前面关于np.fliplr()的回答。下面是一些代码,演示如何构造一维数组,将其转换为二维数组,翻转它,然后再转换回一维数组。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

打印语句被注释掉:

5.59799927506e-05

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

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

用这么小的数组计时是非常无用的。如果你想比较一些东西,最好是用一些需要一段时间的东西,比如3000个或者更多的元素。

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

如果你有一个一维数组…

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

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

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

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

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

Flipud用于1d阵列



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有