Python と NumPy でビッグデータを扱う場合、RAM が足りないので、部分的な結果をディスクに保存するにはどうすればよいでしょうか? 質問する

Python と NumPy でビッグデータを扱う場合、RAM が足りないので、部分的な結果をディスクに保存するにはどうすればよいでしょうか? 質問する

私は、200k 以上のデータポイントを持つ 1000 次元データ用のアルゴリズムを Python で実装しようとしています。numpy、scipy、sklearn、networkx などの便利なライブラリを使用したいと考えています。すべてのポイント間のペアワイズ距離などの操作を実行し、すべてのポイントでクラスタリングを実行したいと考えています。適度な複雑さで必要な操作を実行する実用的なアルゴリズムを実装しましたが、すべてのデータに拡張しようとすると、RAM が不足します。もちろん、200k 以上のデータでペアワイズ距離のマトリックスを作成するには、大量のメモリが必要です。

ここで問題があります。私は本当にこれを RAM の少ない粗悪なコンピューターで実行したいのです。

低 RAM の制約なしにこれを動作させる実行可能な方法はありますか? 所要時間が無限大にならない限り、時間がかかることはまったく問題ではありません。

アルゴリズムを動作させてから 1 時間か 5 時間後に復帰したときに、RAM が不足して停止することがないようにしたいです。これを Python で実装し、numpy、scipy、sklearn、networkx ライブラリを使用できるようにしたいです。すべてのポイントへのペアワイズ距離などを計算できるようにしたいです。

これは実現可能でしょうか? どのように進めればよいでしょうか。何から勉強を始めればよいでしょうか?

ベストアンサー1

を使用するとnumpy.memmap、ファイルに直接マップされた配列を作成できます。

import numpy
a = numpy.memmap('test.mymemmap', dtype='float32', mode='w+', shape=(200000,1000))
# here you will see a 762MB file created in your working directory    

これを従来の配列として扱うことができます: a += 1000。

同じファイルに複数の配列を割り当てて、必要に応じて相互のソースから制御することも可能です。しかし、ここでいくつか厄介なことが起こりました。完全な配列を開くには、まず、次のコードを使用して、前の配列を「閉じる」必要がありますdel

del a    
b = numpy.memmap('test.mymemmap', dtype='float32', mode='r+', shape=(200000,1000))

しかし、配列の一部だけを開くと、同時制御が可能になります。

b = numpy.memmap('test.mymemmap', dtype='float32', mode='r+', shape=(2,1000))
b[1,5] = 123456.
print a[1,5]
#123456.0

素晴らしい!aは と一緒に変更されましたb。変更はすでにディスクに書き込まれています。

コメントする価値のあるもう 1 つの重要な点は です。 の最初の 2 行ではなく、行 150000 と 150001offsetを取得するとします。b

b = numpy.memmap('test.mymemmap', dtype='float32', mode='r+', shape=(2,1000),
                 offset=150000*1000*32/8)
b[1,2] = 999999.
print a[150001,2]
#999999.0

これで、同時操作で配列の任意の部分にアクセスして更新できます。オフセット計算に含まれるバイト サイズに注意してください。したがって、'float64' の場合、この例は 150000*1000*64/8 になります。

その他の参考資料:

おすすめ記事