我尝试使用Python和Numpy/Scipy来实现一个图像处理算法,分析器告诉我很多时间都花在了下面的函数(经常调用)上,这个函数告诉我两个图像之间的平方差之和
def ssd(A,B): s = 0 for i in range(3): s += sum(pow(A[:,:,i] - B[:,:,i],2)) return s
怎么才能快点?谢谢。
yhived7q1#
只是
s = numpy.sum((A[:,:,0:3]-B[:,:,0:3])**2)
(如果形状总是(,,3),我预计可能只是sum((A-B)**2))也可以使用求和方法:((A-B)**2).sum()对不对?
sum((A-B)**2)
((A-B)**2).sum()
uujelgoq2#
这里只需要说明一下,我们也可以使用np.dot:
np.dot
def ssd(A,B): dif = A.ravel() - B.ravel() return np.dot( dif, dif )
这可能比使用np.sum和**2的替代方法更快,也可能更精确,但是如果你想沿着一个指定的轴计算ssd,这就不起作用了,在这种情况下,可能有一个神奇的下标公式使用np.einsum。
np.sum
**2
np.einsum
6ie5vjzr3#
我很困惑你为什么要取i in range(3)。这应该是整个数组,还是只是部分数组?总的来说,你可以用numpy中定义的操作来替换其中的大部分:
i in range(3)
def ssd(A,B): squares = (A[:,:,:3] - B[:,:,:3]) ** 2 return numpy.sum(squares)
这样你就可以做一个操作而不是三个,并且使用numpy.sum可能比内置的sum更好地优化加法。
numpy.sum
sum
nnsrf1az4#
除了Ritsaert Hornstra的回答,得到了2个负分(无可否认,我没有看到它的原始形式...)这是事实。对于大量的迭代,使用'**'操作符或pow(x,y)方法通常需要两倍的时间,而仅仅是手动地将两个对相乘。如果需要,使用math.fabs()方法,如果它抛出NaN的话(有时候它会抛出NaN,特别是当使用int16等时),它仍然只需要两个函数的大约一半的时间。对我知道的最初的问题没有那么重要,但绝对值得知道。
jmp7cifd5#
我不知道带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
r7xajy2e6#
你可以试试这个:
dist_sq = np.sum((A[:, np.newaxis, :] - B[np.newaxis, :, :]) ** 2, axis=-1)
更多细节可以在这里找到('k-最近邻'示例):https://jakevdp.github.io/PythonDataScienceHandbook/02.08-sorting.html
pcrecxhr7#
在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
7条答案
按热度按时间yhived7q1#
只是
(如果形状总是(,,3),我预计可能只是
sum((A-B)**2)
)也可以使用求和方法:
((A-B)**2).sum()
对不对?
uujelgoq2#
这里只需要说明一下,我们也可以使用
np.dot
:这可能比使用
np.sum
和**2
的替代方法更快,也可能更精确,但是如果你想沿着一个指定的轴计算ssd,这就不起作用了,在这种情况下,可能有一个神奇的下标公式使用np.einsum
。6ie5vjzr3#
我很困惑你为什么要取
i in range(3)
。这应该是整个数组,还是只是部分数组?总的来说,你可以用numpy中定义的操作来替换其中的大部分:
这样你就可以做一个操作而不是三个,并且使用
numpy.sum
可能比内置的sum
更好地优化加法。nnsrf1az4#
除了Ritsaert Hornstra的回答,得到了2个负分(无可否认,我没有看到它的原始形式...)
这是事实。
对于大量的迭代,使用'**'操作符或pow(x,y)方法通常需要两倍的时间,而仅仅是手动地将两个对相乘。如果需要,使用math.fabs()方法,如果它抛出NaN的话(有时候它会抛出NaN,特别是当使用int16等时),它仍然只需要两个函数的大约一半的时间。
对我知道的最初的问题没有那么重要,但绝对值得知道。
jmp7cifd5#
我不知道带2次幂的pow()函数是否快。
r7xajy2e6#
你可以试试这个:
更多细节可以在这里找到('k-最近邻'示例):https://jakevdp.github.io/PythonDataScienceHandbook/02.08-sorting.html
pcrecxhr7#
在Ruby语言中,您可以通过以下方式实现这一点