2016-07-11 15 views
1

いくつかの数値解析コードを書く際に、Numpy呼び出しが多く必要な関数でボトルネックを使用しています。パフォーマンスの最適化にどのように取り組むべきかは完全にはわかりません。Python/Numpyでの多くの行列操作の最適化

問題:

機能は、次のように計算することにより、エラーを決定

Error function

コード:

def foo(B_Mat, A_Mat): 
    Temp = np.absolute(B_Mat) 
    Temp /= np.amax(Temp) 
    return np.sqrt(np.sum(np.absolute(A_Mat - Temp*Temp)))/B_Mat.shape[0] 

のうちいくつかの余分なパフォーマンスを絞るための最良の方法だろう何コード?私の最高の行動措置は、一時的な配列を減らすためにCythonで単一のforループで操作の大部分を実行するでしょうか?

+0

あなたはあまりにも関数を呼び出す部分を追加することはできますか? – Kasramvd

答えて

3

算術演算に非常に効率的であることが知られているnumexpr moduleにロードすることができる実装からの特定の機能があります。私たちの場合、具体的には、二乗法、総和法、および絶対計算法を使用して実行することができました。したがって、元のコードの最後のステップを置き換えるnumexprベースのソリューションは、そうのようになる -

import numexpr as ne 

out = np.sqrt(ne.evaluate('sum(abs(A_Mat - Temp**2))'))/B_Mat.shape[0] 

さらなるパフォーマンスの向上は、sが式を評価numexpr」に正規化ステップを埋め込むことによって達成することができます。したがって、numexprを使用するように変更全体の機能は次のようになります -

def numexpr_app1(B_Mat, A_Mat): 
    Temp = np.absolute(B_Mat) 
    M = np.amax(Temp) 
    return np.sqrt(ne.evaluate('sum(abs(A_Mat*M**2-Temp**2))'))/(M*B_Mat.shape[0]) 

ランタイムテスト -

In [198]: # Random arrays 
    ...: A_Mat = np.random.randn(4000,5000) 
    ...: B_Mat = np.random.randn(4000,5000) 
    ...: 

In [199]: np.allclose(foo(B_Mat, A_Mat),numexpr_app1(B_Mat, A_Mat)) 
Out[199]: True 

In [200]: %timeit foo(B_Mat, A_Mat) 
1 loops, best of 3: 891 ms per loop 

In [201]: %timeit numexpr_app1(B_Mat, A_Mat) 
1 loops, best of 3: 400 ms per loop 
関連する問題