2010-11-30 12 views
16

基本的に、numpy行列で代数演算を実行しようとすると、pythonでメモリエラーが発生します。変数uは、2倍の大きな行列です(この2倍の288x288x156行列の場合、この巨大なケースでのみこのエラーが発生しますが、これは大きな行列ではありません)。ここではPythonのエラーは次のとおりです。Python/Numpy MemoryError

Traceback (most recent call last): 

File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc 
t perim erosion flattop\SwSim.py", line 121, in __init__ 
    self.mainSimLoop() 

File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc 
t perim erosion flattop\SwSim.py", line 309, in mainSimLoop 
    u = solver.solve_cg(u,b,tensors,param,fdHold,resid) # Solve the left hand si 
de of the equation Au=b with conjugate gradient method to approximate u 

File "S:\3D_Simulation_Data\Patient SPM Segmentation\20 pc 
t perim erosion flattop\conjugate_getb.py", line 47, in solv 
e_cg 

u = u + alpha*p 

MemoryError 

u = u + alpha*pは失敗し、コードの行です。

alphaは、単なる倍数であり、uおよびrは、(同じサイズの両方の)大きな行列です。

私は特にPythonでのメモリエラーについてよく分かりません。これを解決するための洞察力やヒントは非常に高く評価されます。

おかげ

答えて

39

書き換え。 p = p*alphaは、p*alphaの結果に完全な新しい行列を割り当て、古いpを破棄します。 p*= alphaは同じことを適所で行います。

一般に、大きな行列の場合は、op=という割り当てを試してみてください。

+0

これは非常に役に立ちます。私はこれを知らなかったのです。 – tylerthemiler

5

あなたの行列はdoubleメモリに400メガバイトに出てくる可能性が288x288x156 = 12939264のエントリを持っています。 numpyMemoryErrorに投げると、その機能を実行するために必要なメモリがOSから使用できないということを意味します。

スパース行列を使用することができれば、多くのメモリを節約できます。

p *= alpha 
u += p 

と、これははるかに少ないメモリを使用するに

+2

しかし、私のコンピュータには24GBのRAMが搭載されています...もっと多くのものがウィンドウから利用できることを確認する方法はありますか?編集:私たちが使用しているPythonのバージョンは、何らかの理由で32ビットです。/ Edit2:不幸にも、すべての要素に値があるので、希薄な行列はオプションではありません(問題のような熱方程式)。 – tylerthemiler

+0

ありがとう、私はメモリからいくつかのものをクリアし、今これをロードすることができます。 – tylerthemiler

+0

@tylerthemiler:非公式の64ビットビルドを使用してください。http://www.lfd.uci.edu/~gohlke/pythonlibs/ – endolith

9

私がメモリエラーを避けるために見つけたもう一つのヒントは、手動でgarbage collectionを制御することです。オブジェクトが削除されたり、スコープに入ると、これらの変数に使用されるメモリはガベージコレクションが実行されるまで解放されません。私はいくつかのコードで、大量の配列を使ってMemoryErrorを取得していますが、適切な場所にgc.collect()を呼び出すとこれを避けることができます。

"op ="スタイルの演算子などを使用しても問題が解決しない場合は、このオプションを調べるだけで、gc.collect()がどこからでも呼び出しできるようにするには最適なコーディング手法ではないでしょう。

+0

ええ、私はそれをやり終えた。提案していただきありがとうございます。 – tylerthemiler

+0

MemoryErrorがガベージコレクションを自動的に開始しないのはなぜですか? – endolith

+2

@endolithあなたの 'malloc()'が失敗したときに一時停止してメモリをクリアできないのと同じ理由で - それは遅すぎて_already_失敗しました。あなたはそれから戻ってGCをやり直してやり直すことができますが、NumPyの開発者は、バンドエイドに頼るよりもコードを修正する方がいいと思います。 – PythonNut