什麼是將兩個numpy陣列一起滑動的有效方法?例如,給定將兩個nparray放在一起python
A = [1, 2, 3, 4]
B = [2, 3, 5, 7]
我想計算A和B之間的點積,這是
A.B/|A||B| = (1*2 + 2*3 + .. 4*7)/sqrt(1^2 + 2^2... +4^2) * sqrt(.....)
我如何能夠高效,快速做到這一點?
什麼是將兩個numpy陣列一起滑動的有效方法?例如,給定將兩個nparray放在一起python
A = [1, 2, 3, 4]
B = [2, 3, 5, 7]
我想計算A和B之間的點積,這是
A.B/|A||B| = (1*2 + 2*3 + .. 4*7)/sqrt(1^2 + 2^2... +4^2) * sqrt(.....)
我如何能夠高效,快速做到這一點?
如果您使用numpy的,numpy.dot會做的工作對你
numpy.dot(A,B)
51
爲載體,用最快的規範將是
n = math.sqrt(numpy.dot(A,A.conj()))
,這裏是與其他方法的比較
>>> t1=timeit.Timer("n = math.sqrt(numpy.dot(A,A.conj()))","from __main__ import A,math,numpy")
>>> t2=timeit.Timer("n = math.sqrt(sum(abs(A)**2))","from __main__ import A,math")
>>> t3=timeit.Timer("numpy.linalg.norm(A)","from __main__ import A,numpy")
>>> print "%.2f usec/pass" % (1000000 * t1.timeit(number=100000)/100000)
2.82 usec/pass
>>> print "%.2f usec/pass" % (1000000 * t2.timeit(number=100000)/100000)
13.16 usec/pass
>>> print "%.2f usec/pass" % (1000000 * t3.timeit(number=100000)/100000)
15.68 usec/pass
>>>
除了numpy.dot
,有numpy.linalg.norm
這確實你在找什麼:
from numpy.linalg import norm
from numpy import dot
dot(a,b)/(norm(a)*norm(b))
我猜你想要的平方和,這是norm
默認的開方。這個度量稱爲Frobenius範數或L2範數。如果你想要一個不同的度量標準,比如Manhattan或者L1標準,它只是一個參數。
有沒有辦法讓標準也變快(更快):) – Fraz 2012-04-17 17:30:20
@Fraz:請更新你的問題或打開一個新的問題 – Abhijit 2012-04-17 17:37:45
@Abhijit既然你調用python和而不是numpy(和abs),那麼你是不是第二次作弊? 'numpy.sqrt((numpy.abs(A)** 2).sum())'?我很驚訝,儘管'linalg.norm'變得如此緩慢。我想知道這些時間是否會隨着矢量長度的變化而改變 - 明天可能會測試它,或者如果您願意,可以添加它。 – Hooked 2012-04-18 02:24:04