3 回答
TA贡献1844条经验 获得超8个赞
你真的不能得到任何比O(n)的速度更快,但你可以让你的代码有点用较短,也许更容易阅读numpy.diff和比较sign的差异文件,a并且b:
>>> from numpy import diff, sign
>>> a, b = [1,2,4,3,5], [103,122,800,500,1000]
>>> sign(diff(a))
array([ 1, 1, -1, 1])
>>> all(sign(diff(a)) == sign(diff(b)))
True
>>> a, b = [1,2,4,3,5], [103,122,800,500,100]
>>> all(sign(diff(a)) == sign(diff(b)))
False
这种解决方案的缺点是,它不使用懒惰评价,即它计算和整个比较sign(diff(...))阵列即使的“increasingness”a和b不同之处在于非常第一位置。如果列表很长,您应该考虑使用另一种方法。
TA贡献1824条经验 获得超6个赞
就 O(order notation) 而言,假设列表没有顺序,你不能比线性更好。但是,您可以使用诸如 cython、numba 之类的 Python 编译器来加速您的代码。您使用numba 的代码:
import numpy as np
import numba as nb
@nb.njit()
def vary_together(a, b):
for i in range(1,len(a)):
if (a[i-1] < a[i] and b[i-1] > b[i]) or (a[i-1] > a[i] and b[i-1] < b[i]):
return False
return True
您必须使用大型列表才能看到性能优势。例如,如果:
a = np.array([randint(0,100) for i in range(10000000)])
然后,
vary_together(a, a) # a as both arguments so as to make it complete the loop
与您的解决方案的性能比较如下:
您的解决方案:8.09s 变化
_together:0.2(在第二次运行时为编译时间打折)。
如果您需要在脚本中一次又一次地运行代码,请cache=True在nb.njit装饰器中执行。
TA贡献1843条经验 获得超7个赞
我们可以使用 python 迭代器提供的惰性求值,这意味着一旦它们没有相同的变化符号,我们就不需要继续遍历两个列表(结构)
def compare_variation( a, b ):
a_variations = ( a[ i - 1 ] < a[ i ] for i in range( 1, len( a ) ) )
b_variations = ( b[ i - 1 ] < b[ i ] for i in range( 1, len( b ) ) )
return all( x == y for x, y in zip( a_variations, b_variations ) )
添加回答
举报