web-dev-qa-db-ja.com

pythonとnumpy、十分なRAMではないビッグデータでの作業、ディスクに部分的な結果を保存する方法は?

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

ここで問題が発生します。これは、RAMの量が少ない安っぽいコンピューターで実行したいです。

低RAMの制約なしにこの作業を行うための実行可能な方法はありますか?所要時間が無限にならない限り、はるかに長い時間がかかることは実際には問題ではありません!

私は自分のアルゴリズムを機能させてから1時間または5時間後に戻ってきて、RAMがなくなったために動かないようにしたいです!これをPythonで実装し、numpy、scipy、sklearn、networkxライブラリを使用できるようにしたいと思います。すべてのポイントまでのペアワイズ距離を計算できるようにしたいなど

これは可能ですか?そして、私はそれについてどうやって行きますか、私は何を読み始めますか?

よろしく//メスマー

42
Ekgren

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

すごい! abとともに変更されました。そして、変更はすでにディスクに書き込まれています。

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

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になります。

その他の参照:

57