web-dev-qa-db-ja.com

メモリエラーとリスト制限?

科学的な目的で、大規模な(非常に)行列(Markovチェーン)を作成する必要があります。 20301要素のリスト(=行列の1行)に入れた計算を実行します。次のマルコフ手順を進めるには、メモリ内のこれらのデータがすべて必要ですが、マルコフチェーンのウォークスルーが遅くなる場合でも、必要に応じて他の場所(ファイルなど)に保存できます。私のコンピューター(科学実験室):バイキセノン6コア/各12スレッド、12 GBメモリー、OS:win64

  Traceback (most recent call last):
  File "my_file.py", line 247, in <module>
    ListTemp.append(calculus)
MemoryError

計算結果の例:9.233747520008198e-102(はい、1/9000以上です)

19766番目の要素を保存すると、エラーが発生します。

ListTemp[19766]
1.4509421012263216e-103

さらに進むと

Traceback (most recent call last):
  File "<pyshell#21>", line 1, in <module>
    ListTemp[19767]
IndexError: list index out of range

そのため、このリストには19767ループでメモリエラーがありました。

質問:

  1. リストにメモリ制限はありますか? 「リストごとの制限」または「スクリプトごとのグローバル制限」ですか?

  2. これらの制限をバイパスする方法は?考えられる可能性はありますか?

  3. Numpy、python64を使用すると役立ちますか?それらのメモリ制限は何ですか?他の言語はどうですか?

62
Taupi

最初に、 Python配列を取得できる大きさ および でこぼこ、長い配列の問題 を参照してください。

第二に、唯一の本当の制限は、あなたが持っているメモリの量とシステムがメモリ参照を保存する方法から来ます。リストごとの制限はないため、Pythonはメモリがなくなるまで実行されます。 2つの可能性:

  1. 古いOSまたはプロセスに制限された量のメモリを使用させるOSで実行している場合、Pythonプロセスがアクセスできるメモリの量を増やす必要があります。
  2. チャンクを使用してリストを分割します。たとえば、リストの最初の1000要素を実行し、それらをディスクにピクルして保存してから、次の1000要素を実行します。それらを使用するには、メモリ不足にならないように一度に1つのチャンクを選択解除します。これは基本的に、データベースがRAMに収まるよりも多くのデータを処理するために使用する手法と同じです。
52

表示されているMemoryError例外は、使用可能なRAMが不足した直接の結果です。これは、Windowsによって課せられたプログラムあたり2GBの制限( 2ビットプログラム )、またはコンピューターで利用可能なRAMの不足が原因である可能性があります。 (これは link は前の質問に対するものです)。

64ビットコピーのWindowsを使用している場合、64ビットコピーのPythonを使用して2GBを拡張できるはずです。

配列全体を計算する前にPythonがIndexError例外をヒットしたため、MemoryErrorが発生します。これもメモリの問題です。

この問題を回避するには、Pythonの64ビットコピーを使用するか、結果をファイルに書き込む方法を見つけます。このために、numpyの メモリマッピングされた配列 を見てください。

実際のデータはディスクに書き込まれ、その一部のみがメモリに保持されるため、計算セット全体をこれらの配列のいずれかに実行できるはずです。

25
thomas

Pythonによるメモリ制限はありません。ただし、RAMが不足するとMemoryErrorが返されます。 listに20301個の要素があると言います。これは単純なデータ型(たとえば、int)でメモリエラーを引き起こすには小さすぎるように見えますが、各要素自体が大量のメモリを占有するオブジェクトである場合、メモリが不足している可能性があります。

IndexErrorは、おそらくListTempに19767個の要素(0〜19766のインデックス)しかなく、最後の要素を超えてアクセスしようとしているために発生した可能性があります。

あなたが何をしようとしているのかを正確に知ることなく、限界に達することを避けるためにあなたができることを言うのは難しいです。 numpyを使用すると役立つ場合があります。大量のデータを保存しているようです。すべての段階ですべてを保存する必要はないかもしれません。しかし、知らずに言うことは不可能です。

7
MAK

この問題を回避したい場合は、シェルフも使用できます。次に、処理できるマシン容量のサイズになるファイルを作成し、必要な場合にのみRAMに配置します。基本的には、HDに書き込み、情報を断片に戻して処理できるようにします。

バイナリファイルを作成し、ローカル変数を保持してそれを保持する場合は情報が既に存在するかどうかを確認し、そうでない場合は必要と思われるデータを書き込みます。

Data = shelve.open('File01')
   for i in range(0,100):
     Matrix_Shelve = 'Matrix' + str(i)
     if Matrix_Shelve in Data:
        Matrix_local = Data[Matrix_Shelve]
     else:
        Data[Matrix_Selve] = 'somenthingforlater'

それはあまりにも古風に聞こえないことを願っています。