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 ) )
添加回答
舉報