2016-08-10 19 views
1

私は共起する行列を作成しています。これは、1Mから1Mの整数値のサイズです。 行列が作成された後、私が実行する唯一の操作は、各行(または列は対称行列であるため)ごとに上位N個の値を取得することです。Pythonで疎な行列を徐々に作成するには?

私はそれをメモリに収めるには、疎な(sparse)マトリックスを作成する必要があります。大きなファイルから入力データを読み込み、2つのインデックス(行、列)のインクリメンタルな更新を更新します。

Sparse dok_matrixのサンプルコードでは、事前に行列のサイズを宣言するように指定しています。私は私の行列(1m×1m)の上限を知っていますが、実際にはそれよりも小さいかもしれません。 事前にサイズを指定する必要がありますか、それともインクリメンタルに作成するだけですか?数日前から

import numpy as np 
from scipy.sparse import dok_matrix 
S = dok_matrix((5, 5), dtype=np.float32) 
for i in range(5): 
    for j in range(5): 
     S[i, j] = i + j # Update element 
+1

は、あなたが本当にすべてで行列が必要なのでしょうか? –

+0

最終的に作成された共起行列の各行から上位N個の値を抽出します。入力ファイルから読み込んだ各要素について、(row_i、col_j)の共発生行列の値をインクリメントする。 – cybergeek654

+0

代わりに、(行、列)をキーとして辞書を使用できますか? –

答えて

2

A SOの質問、creating sparse matrix of unknown size、ファイルから読み取られたデータからスパース行列の作成について協議。 OPがlil形式を使用したかった。 coo形式の入力配列の作成をお勧めします。

その他の質問では、dokがディクショナリサブクラスであっても、普通の辞書に値を追加するほうが、dokの行列に値を追加する方が速いことがわかりました。インデックス作成の方法にはかなりのオーバーヘッドがあります。dok場合によっては、タプルキーを使ってdictを作成し、updateを使って値を定義済みのdokに追加することを提案しました。しかし、あなたのケースではcooの方が良いと思われます。

doklilは、インクリメンタルな構造に最適なフォーマットですが、どちらもpythonのリストやdictメソッドに比べて優れていません。

各行のtop N valuesについては、私はそれを覚えていることを思い出していますが、しばらくしてから、良い手続きを取ることはできません。おそらくlilまたはcsrのような行指向のフォーマットが必要です。

質問には、「作成時にサイズを指定する必要がありますか?はい。疎な行列は、フォーマットに関係なく、ゼロ以外の値しか格納しないので、大きすぎる行列を作成する際に害はほとんどありません。

またはcooの形式のものは、少なくともshapeにあるとは思えません。少なくともデータの保存や作成に関しては考えられません。 lilcsrにはいくつかの追加値があります。あなたが本当にこれを調べる必要がある場合は、値がどのように格納されているかを読んで、小さな行列で遊ぶ。 dokフォーマットのすべてのコードが

は/ usr/libに/のpython3/distの中にPythonのであるように見えます

==================

パッケージ/ scipy/sparse/dok。それはすべてをステップ実行します - 私はdokはあなたが1M x 1Mに行列を初期と100 x 100にサイズを変更したい場合は、あなたがそうすることができるので、resize方法

d.resize? 
Signature: d.resize(shape) 
Docstring: 
Resize the matrix in-place to dimensions given by 'shape'. 

Any non-zero elements that lie outside the new shape are removed. 
File:  /usr/lib/python3/dist-packages/scipy/sparse/dok.py 
Type:  method 

を持っていないことがわかり、ファイル、PY

スキャンキーを押して、新しい範囲外のものがないことを確認します。主なアクションは形状パラメータを変更することですが、それは安くはありません。

newM, newN = shape 
    M, N = self.shape 
    if newM < M or newN < N: 
     # Remove all elements outside new dimensions 
     for (i, j) in list(self.keys()): 
      if i >= newM or j >= newN: 
       del self[i, j] 
    self._shape = shape 

外側のキーがないことがわかっている場合は、シェイプを直接変更することができます。他の疎フォーマットにはresizeメソッドがありません。

In [31]: d=sparse.dok_matrix((10,10),int) 

In [32]: d 
Out[32]: 
<10x10 sparse matrix of type '<class 'numpy.float64'>' 
    with 0 stored elements in Dictionary Of Keys format> 

In [33]: d.resize((5,5)) 

In [34]: d 
Out[34]: 
<5x5 sparse matrix of type '<class 'numpy.float64'>' 
    with 0 stored elements in Dictionary Of Keys format> 

In [35]: d._shape=(9,9) 

In [36]: d 
Out[36]: 
<9x9 sparse matrix of type '<class 'numpy.float64'>' 
    with 0 stored elements in Dictionary Of Keys format> 

も参照してください:あなたが唯一の各行から先頭の値を抽出するために必要がある場合は

Why are lil_matrix and dok_matrix so slow compared to common dict of dicts?

Get top-n items of every row in a scipy sparse matrix

関連する問題