いくつかのデータを処理していて、結果を3つの辞書に保存し、Pickleを使用してディスクに保存しました。各辞書には500〜1000MBがあります。
今私はそれらをロードしています:
import pickle
with open('dict1.txt', "rb") as myFile:
dict1 = pickle.load(myFile)
ただし、最初の辞書をロードすると、次のようになります。
*** set a breakpoint in malloc_error_break to debug
python(3716,0xa08ed1d4) malloc: *** mach_vm_map(size=1048576) failed (error code=3)
*** error: can't allocate region securely
*** set a breakpoint in malloc_error_break to debug
Traceback (most recent call last):
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 858, in load
dispatch[key](self)
File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1019, in load_empty_dictionary
self.stack.append({})
MemoryError
これを解決する方法は?私のコンピュータには16GBのRAMがあるので、800MBの辞書の読み込みがクラッシュするのは珍しいことです。また、辞書の保存中に問題がなかったことも珍しいことです。
さらに、将来的にはより多くのデータを処理して辞書を大きくする予定です(ディスク上で3〜4GB)ので、効率を改善する方法についてアドバイスをいただければ幸いです。
辞書のデータがnumpy
配列の場合、joblib
とklepto
の両方がnumpy.array
の最小状態表現の使用方法を理解しているため、大きな配列の選択を効率的にするパッケージ(klepto
やjoblib
など)があります。 array
データがない場合は、klepto
を使用して、辞書エントリを(単一のファイルではなく)複数のファイルまたはデータベースに保存することをお勧めします。
非常に密接に関連する質問への私の答えを参照してください https://stackoverflow.com/a/25244747/23794 、単一のファイルではなく複数のファイルにピクルスすることに問題がない場合は、保存したい/データを並行して読み込むか、ストレージ形式とバックエンドを簡単に試して、どちらが自分のケースに最適かを確認したいと考えています。他の潜在的な改善については https://stackoverflow.com/a/21948720/23794 も参照してください。また、ここでも: https://stackoverflow.com/a/24471659/23794 。
上記のリンクで説明されているように、klepto
を使用できます。これにより、共通のAPIを使用して、辞書をディスクまたはデータベースに簡単に保存できます。 klepto
を使用すると、ストレージ形式(pickle
、json
など)を選択することもできます。また、HDF5
(またはSQLデータベース)は、並列アクセスを可能にするため、もう1つの優れたオプションです。 klepto
は、特殊なピクルス形式(numpy
など)と圧縮(データへのアクセス速度ではなくサイズを重視する場合)の両方を利用できます。
klepto
は、「オールインワン」ファイルまたは「one-entry-per」ファイルで辞書を保存するオプションを提供し、マルチプロセッシングまたはマルチスレッドを活用することもできます。つまり、辞書アイテムを並列のバックエンド。例については、上記のリンクを参照してください。
これはpickleに固有の問題であり、かなり少量のデータでの使用を目的としています。辞書のサイズは、メモリにロードされると、ディスクよりも何倍も大きくなります。
100MBのpickleファイルをロードした後、ほぼ1GB程度の辞書が作成される可能性があります。オーバーヘッドを計算するための公式がWeb上にいくつかありますが、そのような量のデータにはMySQLやPostgreSQLなどの適切なデータベースを使用することをお勧めします。