NumPyは非常に便利なライブラリです。これを使用して、非常に大きな行列 (10000 x 10000) を簡単に処理できることがわかりましたが、それよりも大きな行列 (50000 x 50000 の行列を作成しようとすると、失敗します)。明らかに、これは大規模なメモリ要件によるものです。
NumPy でネイティブに巨大な行列 (たとえば 100 万 x 100 万) を何らかの方法で (数テラバイトの RAM を持たずに) 作成する方法はありますか?
PyTables と NumPy がその方法です。
PyTables は、データを HDF 形式でディスクに保存し、オプションで圧縮します。私のデータセットはしばしば 10 倍に圧縮されます。これは、数千万または数億の行を扱う場合に便利です。また、非常に高速です。私の 5 年前のラップトップは、SQL に似た GROUP BY 集計を 1 秒あたり 1,000,000 行で実行してデータを処理できます。Python ベースのソリューションとしては悪くありません!
NumPy 再配列としてデータに再びアクセスするのは、次のように簡単です。
data = table[row_from:row_to]
HDF ライブラリは、関連するデータ チャンクの読み取りと NumPy への変換を処理します。
スパース行列を処理するには、その上にあるscipy
パッケージが必要です。スパース行列オプションの詳細については、こちらnumpy
を参照してください。scipy
64 ビット オペレーティング システムと 64 ビット バージョンの Python/NumPy を使用していることを確認してください。32 ビット アーキテクチャでは、通常 3GB のメモリをアドレス指定できることに注意してください (メモリ マップド I/O などで約 1GB が失われます)。
64 ビットおよび使用可能な RAM よりも大きい配列を使用すると、仮想メモリを使用できますが、スワップする必要がある場合は速度が低下します。また、メモリ マップ (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
私がnumpyについて知っている限り、いいえ、しかし私は間違っている可能性があります.
この代替ソリューションを提案できます。マトリックスをディスクに書き込み、チャンクでアクセスします。HDF5 ファイル形式をお勧めします。透過的に必要な場合は、ndarray インターフェイスを再実装して、ディスクに格納されたマトリックスをメモリにページ付けすることができます。ディスク上でデータを同期するためにデータを変更する場合は注意してください。
通常、大きな行列を扱うときは、それらをSparse Matricesとして実装します。
numpy がスパース行列をサポートしているかどうかはわかりませんが、代わりにこれを見つけました。