2012-04-17 48 views
1

什么是将两个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(.....) 

我如何能够高效,快速做到这一点?

回答

5

如果您使用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 
>>> 
+0

有没有办法让标准也变快(更快):) – Fraz 2012-04-17 17:30:20

+0

@Fraz:请更新你的问题或打开一个新的问题 – Abhijit 2012-04-17 17:37:45

+0

@Abhijit既然你调用python和而不是numpy(和abs),那么你是不是第二次作弊? 'numpy.sqrt((numpy.abs(A)** 2).sum())'?我很惊讶,尽管'linalg.norm'变得如此缓慢。我想知道这些时间是否会随着矢量长度的变化而改变 - 明天可能会测试它,或者如果您愿意,可以添加它。 – Hooked 2012-04-18 02:24:04

3

除了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标准,它只是一个参数。