2017-07-12 15 views
1

次のようにIは、3-D numpyのアレイflowを有する:スピードアップ各xに対して角度計算を、マトリックス中のY点

flow = np.random.uniform(low=-1.0, high=1.0, size=(720,1280,2)) 
# Suppose flow[0] are x-coordinates. flow[1] are y-coordinates. 

はそれぞれX、Yポイントの角度を計算する必要があります。ここで私はそれを実装している方法です。

def calcAngle(a): 
    assert(len(a) == 2) 
    (x, y) = a 
    # angle_deg = 0 
    angle_deg = np.angle(x + y * 1j, deg=True) 
    return angle_deg 

fangle = np.apply_along_axis(calcAngle, axis=2, arr=flow) 
# The above statement takes 14.0389318466 to execute 

各点での角度の計算は、私のMacBook Pro上で実行するために14.0389318466 secondsかかります。

おそらく、各ピクセルを1つずつ処理するのではなく、いくつかのマトリックス操作を使用して、これを高速化できる方法はありますか?

答えて

3

numpy.angleは、ベクトル化された操作をサポートします。だから、ちょうどそうように、最終的な出力のために第1及び第2の列のスライスに供給 -

fangle = np.angle(flow[...,0] + flow[...,1] * 1j, deg=True) 

検証 -

In [9]: flow = np.random.uniform(low=-1.0, high=1.0, size=(720,1280,2)) 

In [17]: out1 = np.apply_along_axis(calcAngle, axis=2, arr=flow) 

In [18]: out2 = np.angle(flow[...,0] + flow[...,1] * 1j, deg=True) 

In [19]: np.allclose(out1, out2) 
Out[19]: True 

ランタイム試験 -

In [10]: %timeit np.apply_along_axis(calcAngle, axis=2, arr=flow) 
1 loop, best of 3: 8.27 s per loop 

In [11]: %timeit np.angle(flow[...,0] + flow[...,1] * 1j, deg=True) 
10 loops, best of 3: 47.6 ms per loop 

In [12]: 8270/47.6 
Out[12]: 173.73949579831933 

173x+スピードアップ!

+0

ありがとう!あなたが指定した行列ソリューションを既に試してみたところ、何らかのエラーが発生していると思いました。たぶん私は早く間違いをした。 – vishal

4

あなたはラジアンで角度を取得するためにnumpy.arctan2()を使用して、numpy.rad2deg()を度に変換することができます

fangle = np.rad2deg(np.arctan2(flow[:,:,1], flow[:,:,0])) 

自分のコンピュータ上で、これは少し速くDivakarのバージョンよりも次のとおりです。

In [17]: %timeit np.angle(flow[...,0] + flow[...,1] * 1j, deg=True) 
10 loops, best of 3: 44.5 ms per loop 

In [18]: %timeit np.rad2deg(np.arctan2(flow[:,:,1], flow[:,:,0])) 
10 loops, best of 3: 35.4 ms per loop 

np.angle()を使用するより効率的な方法は、flowの複雑なビューを作成することです。 flow形状(m, n, 2)有するタイプnp.float64の配列である場合、flow.view(np.complex128)[:,:,0]形状(m, n)有するタイプnp.complex128の配列であろう。

fangle = np.angle(flow.view(np.complex128)[:,:,0], deg=True) 

これは高速rad2deg続いarctan2を(使用するよりsmidgeであるように見えるが、違いがあります遠くないtimeitの測定ノイズ以上):flowは、いくつかのtranposeとして作成された場合、これは動作しない場合がありますことを

In [47]: %timeit np.angle(flow.view(np.complex128)[:,:,0], deg=True) 
10 loops, best of 3: 35 ms per loop 

は注意他の配列、または1より大きいステップを使用する別の配列のスライスとして表示されます。

+0

ニース!これは複素数では機能しないように見えますが、どちらもOPのサンプルデータではありません。 – Divakar

+0

入力が複雑な場合、OPのメソッドは機能しませんので、私はそのケースについて心配する必要はないと思います。 –

+0

Nahさん、OPの方法がうまくいきます。 – Divakar

関連する問題