16

PythonとNumpy/Scipyを使用して画像処理アルゴリズムを実装しようとしています。プロファイラーは、次の関数(頻繁に呼び出される)に多くの時間が費やされていることを教えてくれます。これは、2つの画像間の二乗の差の合計を教えてくれます。

def ssd(A,B):
    s = 0
    for i in range(3):
        s += sum(pow(A[:,:,i] - B[:,:,i],2))
    return s

どうすればこれをスピードアップできますか?ありがとう。

4

7 に答える 7

48

ただ

s = numpy.sum((A[:,:,0:3]-B[:,:,0:3])**2)

(私が期待するのはsum((A-B)**2)、形状が常に(、、 3)である場合だけです)

sumメソッドを使用することもできます。((A-B)**2).sum()

右?

于 2010-02-17T21:47:11.273 に答える
5

言うまでもなく、次のものも使用できますnp.dot

def ssd(A,B):
  dif = A.ravel() - B.ravel()
  return np.dot( dif, dif )

np.sumこれは、とを使用する他の方法よりも少し速く、おそらくより正確かもしれませんが**2、指定された軸に沿ってssdを計算する場合は機能しません。その場合、を使用した魔法の添え字式があるかもしれませんnp.einsum

于 2019-10-28T10:16:09.263 に答える
2

なぜあなたが取っているのか混乱していますi in range(3)。それはアレイ全体なのか、それとも一部なのか?

全体として、これのほとんどをnumpyで定義された操作に置き換えることができます。

def ssd(A,B):
    squares = (A[:,:,:3] - B[:,:,:3]) ** 2
    return numpy.sum(squares)

このようにして、3つではなく1つの操作を実行でき、を使用numpy.sumすると、組み込みよりも追加を最適化できる場合がありますsum

于 2010-02-17T21:50:06.223 に答える
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
于 2010-02-17T21:47:52.147 に答える
1

2つの否定的なマークを得たRitsaertHornstraの答えに加えて(確かに私はそれを元の形で見ていませんでした...)

これは実際には真実です。

反復回数が多い場合、「**」演算子またはpow(x、y)メソッドを使用する場合、ペアを手動で乗算する場合の2倍の時間がかかることがよくあります。必要に応じて、NaNをスローする場合はmath.fabs()メソッドを使用します(これは特にint16などを使用する場合に実行されます)。それでも、指定された2つの関数の約半分の時間しかかかりません。

私が知っている元の質問にはそれほど重要ではありませんが、間違いなく知っておく価値があります。

于 2010-02-23T15:41:22.163 に答える
-1

あなたはこれを試すことができます:

dist_sq = np.sum((A[:, np.newaxis, :] - B[np.newaxis, :, :]) ** 2, axis=-1)

詳細については、こちらをご覧ください(「k最近傍法」の例): https ://jakevdp.github.io/PythonDataScienceHandbook/02.08-sorting.html

于 2018-04-27T15:56:38.823 に答える
-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
于 2015-01-29T11:54:14.157 に答える