4

私はすでに次のコードを書いています。これはまさに私が望んでいることを実行しますが、遅すぎます。高速化する方法があることは確かですが、どうすればよいかわかりません。コードの最初の部分は、何がどの形状であるかを示すだけです。

測定値の 2 つの画像 (VV1およびHH1)シミュレートさ れた
値とシミュレーVVトされた値の両方が 3つのパラメーター (値に対してHH事前に計算されたもの) に依存する事前計算された値(101, 31, 11)
VVHH

VV1 = numpy.ndarray((54, 43)).flatten()
HH1 = numpy.ndarray((54, 43)).flatten()
precomp = numpy.ndarray((101, 31, 11, 2))

変化させる 3 つのパラメータのうちの 2 つ

comp = numpy.zeros((len(parameter1), len(parameter2)))

for i,(vv,hh) in enumerate(zip(VV1,HH1)):
    comp0 = numpy.zeros((len(parameter1),len(parameter2)))
    for j in range(len(parameter1)):
        for jj in range(len(parameter2)):
            comp0[j,jj] = numpy.min((vv-precomp[j,jj,:,0])**2+(hh-precomp[j,jj,:,1])**2)
    comp+=comp0

私がしなければならないことは明らかですが、できる限り多くの for ループを取り除くことですが、numpy.minより多くの次元で作業するときに適切に動作させる方法がわかりません。

2 番目のこと (ベクトル化できる場合はそれほど重要ではありませんが、それでも興味深い) は、RAM ではなく CPU 時間がほとんどかかることに気付きましたが、すでに長い間検索しましたが、「parfor」のようなものを記述する方法が見つかりません。 " matlab の "for" の代わりに ( @parallelfor ループを別のメソッドに入れるだけで、デコレータを作成することは可能ですか?)

編集:Janne Karilaへの返信:ええ、それは間違いなくそれを大幅に改善します、

for (vv,hh) in zip(VV1,HH1):
    comp+= numpy.min((vv-precomp[...,0])**2+(hh-precomp[...,1])**2, axis=2)

間違いなくはるかに高速ですが、外側の for ループも削除する可能性はありますか? または何かを使用して、forループを並列にする方法はあり@parallelますか?

4

3 に答える 3

0

ループを並列化する 1 つの方法は、 を使用するような方法でループを構築することmapです。その場合、 をmultiprocessing.Pool使用してパラレル マップを使用できます。

私はこれを変更します:

for (vv,hh) in zip(VV1,HH1):
    comp+= numpy.min((vv-precomp[...,0])**2+(hh-precomp[...,1])**2, axis=2)

このようなものに:

def buildcomp(vvhh):
    vv, hh = vvhh
    return numpy.min((vv-precomp[...,0])**2+(hh-precomp[...,1])**2, axis=2)

if __name__=='__main__':
    from multiprocessing import Pool
    nthreads = 2
    p = Pool(nthreads)
    complist = p.map(buildcomp, np.column_stack((VV1,HH1)))
    comp = np.dstack(complist).sum(-1)

は、3 番目の軸を追加し、それに沿って合計するため、それぞれがであるdstackと仮定することに注意してください。リストを作成し、積み重ねてから合計する必要があるため、これは少し遅くなりますが、これらはすべて並列またはnumpy操作です。comp.ndim2

zipまた、 numpy operationに変更しましたnp.column_stack。これzipは、長い配列の場合、それらが既に 1 次元の配列であると仮定すると、はるかに遅いためです (これはあなたの例にあります)。

これを簡単にテストすることはできません。問題がある場合は、お気軽にお知らせください。

于 2013-05-17T15:01:31.813 に答える