我正在尝试使用Python和Numpy / Scipy来实现图像处理算法。分析器告诉我在下面的函数(经常调用)中花费了大量时间,它告诉我两个图像之间的平方差异总和
def ssd(A,B):
s = 0
for i in range(3):
s += sum(pow(A[:,:,i] - B[:,:,i],2))
return s
我怎样才能加快速度?感谢。
答案 0 :(得分:35)
只需
s = numpy.sum((A[:,:,0:3]-B[:,:,0:3])**2)
(如果形状总是(,,3),我预计可能只有sum((A-B)**2)
您还可以使用sum方法:((A-B)**2).sum()
右?
答案 1 :(得分:1)
我不知道具有电源2的pow()功能是否会很快。尝试:
def ssd(A,B):
s = 0
for i in range(3):
s += sum((A[:,:,i] - B[:,:,i])*A[:,:,i] - B[:,:,i])
return s
答案 2 :(得分:1)
我很困惑你为什么要服用i in range(3)
。这应该是整个阵列,还是仅仅是一部分?
总的来说,您可以使用numpy中定义的操作替换大部分内容:
def ssd(A,B):
squares = (A[:,:,:3] - B[:,:,:3]) ** 2
return numpy.sum(squares)
这样您可以执行一次操作而不是三次操作,使用numpy.sum
可以比内置sum
更好地优化添加。
答案 3 :(得分:1)
继Ritsaert Hornstra的答案得到2个负面评价(诚然,我没有看到它的原始形式......)
事实确实如此。
对于大量迭代,使用'**'运算符或pow(x,y)方法通常需要两倍的时间来手动将这些对相乘。如果必要的话,使用math.fabs()方法,如果它抛出NaN(有时特别是在使用int16s时),并且它仍然只需要给出两个函数的大约一半的时间。
对于我所知道的原始问题并不重要,但绝对值得了解。
答案 4 :(得分:0)
你可以尝试这个:
dist_sq = np.sum((A[:, np.newaxis, :] - B[np.newaxis, :, :]) ** 2, axis=-1)
可以在这里找到更多细节('k-Nearest Neighbors'示例): https://jakevdp.github.io/PythonDataScienceHandbook/02.08-sorting.html
答案 5 :(得分:0)
只需提及一个人也可以使用np.dot
:
def ssd(A,B):
dif = A.ravel() - B.ravel()
return np.dot( dif, dif )
这可能比使用np.sum
和**2
的方法更快,更准确,但如果要沿指定的轴计算ssd,则不起作用。在这种情况下,可能会有使用np.einsum
的神奇下标公式。
答案 6 :(得分:-3)
在Ruby语言中,您可以通过这种方式实现这一目标
def diff_btw_sum_of_squars_and_squar_of_sum(from=1,to=100) # use default values from 1..100.
((1..100).inject(:+)**2) -(1..100).map {|num| num ** 2}.inject(:+)
end
diff_btw_sum_of_squars_and_squar_of_sum #call for above method