NumPyは非常に便利なライブラリであり、それを使用することで、非常に大きな(10000 x 10000)行列を簡単に処理できることがわかりましたが、はるかに大きな行列(50000 x 50000の行列を作成しようとしています)に苦労し始めます。失敗します)。明らかに、これは大量のメモリ要件のためです。
なんらかの方法で(数テラバイトのRAMを使用せずに)NumPyでネイティブに巨大なマトリックス(たとえば100万×100万)を作成する方法はありますか?
回答:
PyTablesとNumPyがその方法です。
PyTablesは、オプションの圧縮を使用して、HDF形式でデータをディスクに保存します。私のデータセットはしばしば10倍の圧縮を取得します。これは、数千万または数億の行を処理するときに便利です。また、非常に高速です。私の5歳のラップトップは、SQLのようなGROUPBY集計を1,000,000行/秒で実行してデータを処理できます。Pythonベースのソリューションとしては悪くありません!
NumPyリアレイとしてデータに再度アクセスするのは、次のように簡単です。
data = table[row_from:row_to]
HDFライブラリは、関連するデータチャンクの読み取りとNumPyへの変換を処理します。
numpy.array
sはメモリ内に存在することを意図しています。RAMよりも大きい行列を処理する場合は、それを回避する必要があります。あなたが従うことができる少なくとも2つのアプローチがあります:
scipy.sparse.csc_matrix
。numpy.memmapを使用して、ディスク上のファイルをメモリマップできるはずです。新しいPythonと64ビットマシンでは、すべてをメモリにロードせずに、必要なアドレス空間が必要です。OSは、ファイルの一部のみをメモリに保持するように処理する必要があります。
スパース行列を処理するには、必要scipy
の上に座って、パッケージをnumpy
-を参照して、ここでスパース行列のオプションの詳細についてはscipy
あなたを与えます。
64ビットオペレーティングシステムと64ビットバージョンのPython / NumPyを使用していることを確認してください。32ビットアーキテクチャでは、通常3GBのメモリをアドレス指定できることに注意してください(メモリマップドI / Oなどで約1GBが失われます)。
使用可能なRAMよりも大きい64ビットおよびthings配列を使用すると、仮想メモリを使用できますが、スワップする必要がある場合は処理が遅くなります。また、メモリマップ(numpy.memmapを参照)は、ディスク上の巨大なファイルをメモリにロードせずに操作する方法ですが、これを有効にするには、64ビットのアドレス空間が必要です。PyTablesはあなたのためにもこれのほとんどを行います。
少しアルファ版ですが、http://blaze.pydata.org/がこれの解決に取り組んでいるようです。
単純な解決策の1つは、マトリックスアイテムにカスタムタイプを使用することです。あなたが必要とする数の範囲に基づいて、あなたはdtype
あなたのアイテムのためにマニュアルと特別に小さいものを使うことができます。Numpyはデフォルトでオブジェクトの最大の型を考慮するため、これは多くの場合に役立つアイデアです。次に例を示します。
In [70]: a = np.arange(5)
In [71]: a[0].dtype
Out[71]: dtype('int64')
In [72]: a.nbytes
Out[72]: 40
In [73]: a = np.arange(0, 2, 0.5)
In [74]: a[0].dtype
Out[74]: dtype('float64')
In [75]: a.nbytes
Out[75]: 32
そしてカスタムタイプで:
In [80]: a = np.arange(5, dtype=np.int8)
In [81]: a.nbytes
Out[81]: 5
In [76]: a = np.arange(0, 2, 0.5, dtype=np.float16)
In [78]: a.nbytes
Out[78]: 8
テラバイトのRAMなしで2,500,000,000要素のマトリックスを処理する方法を尋ねていますか?
80億バイトのRAMなしで20億のアイテムを処理する方法は、マトリックスをメモリに保持しないことです。
これは、ファイルシステムから断片的にフェッチするためのはるかに高度なアルゴリズムを意味します。
(row, column, value)
するエントリのリストを保存できる場合は、ゼロごとに4バイトを使用する必要はありません。
私がnumpyについて知っている限り、いいえ、しかし私は間違っている可能性があります。
この代替ソリューションを提案できます。ディスクにマトリックスを書き込み、チャンクでアクセスします。HDF5ファイル形式をお勧めします。透過的に必要な場合は、ndarrayインターフェイスを再実装して、ディスクに保存されたマトリックスをメモリにページ分割できます。データを変更してディスクに同期する場合は注意が必要です。