python数列翻转_关于python:最有效的⽅法来反转numpy数
信不信由你,在分析了我当前的代码之后,numpy数组反转的重复操作占⽤了⼤量的运⾏时间。我现在拥有的是基于视图的通⽤⽅法:
reversed_arr = arr[::-1]
有没有其他⽅法可以更有效地做到这⼀点,或者这只是我对不切实际的⿇⽊表现的痴迷造成的幻觉?
呃。。。arr[::-1]只是返回⼀个相反的视图。它尽可能快,⽽且不依赖于数组中的项⽬数,因为它只会改变步幅。你要反转的是⼀个⿇⽊的数组吗?
是的,确实,arr是⼀个⿇⽊的数组。
六羟甲基三聚氰胺六甲醚。。。好吧,在我的笔记本电脑上,不管阵列的长度是多少,都需要670纳秒。如果这是您的瓶颈,您可能需要切换语⾔…我很肯定你不会到⼀个更快的⽅法来逆转⼀个⿇⽊的数组。祝你好运,⽆论如何!
每击670纳秒和我得到的差不多。运⾏整个函数的总时间约为2~3秒,其中恢复时间约为1/3,即1秒。因为我要运⾏这个函数数百万次,所以我认为这是⼀个瓶颈。如果这确实是我能得到的最好的,⼤概我只能决定和它⼀起⽣活。谢谢!
好吧,你⼀定要在⼀个循环中运⾏它吗?在某些情况下,最好是⽤数百万个项创建⼀个⿇⽊的数组,然后对整个数组进⾏操作。即使您正在执⾏有限差分法或类似的操作,结果取决于前⾯的结果,有时也可以执⾏此操作。(有时强调…)⽆论如何,如果速度是主要⽬标,Fortran 仍然是王者。以东⼗⼀〔⼆〕是你的朋友!⽤另⼀种语⾔编写算法的性能关键部分(特别是在科学计算中)并从Python中调⽤它通常是值得的。祝你好运!
我刚刚了解了numpy.flipud(),不知道它与arr[::-1]的性能相⽐如何。
@贝托。因为它是arr[::-1]的包装器,所以速度较慢:github/numpy/numpy/blob/master/numpy/lib/twodim ou base.py。搜索def flipud。这个函数实际上有四⾏长。
谢谢@madpoisical(顺便说⼀下,在github上,单击⾏号,然后复制链接以获取:
github/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()python获取数组长度
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阵列

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。