2013-03-01 21 views
5

大規模だが疎配列があり、行を列に入れ替えて配列を並べ替える必要があります。 scipy.sparseでこれを行う良い方法は何ですか?行と列を交換して疎配列を並べ替える

いくつかの問題

  • 私は、彼らがスパース構造を変更するランダム好きなようにその置換行列は、この作業に適しているとは思いません。必要なスワップがわずかであっても、操作によって、すべての列または行が常に「乗算」されます。

  • このタスクではscipy.sparseの中で最も疎なマトリックス表現は何ですか?

  • ご提案は大歓迎です。

この質問は必ずしもscipy固有のものではない答えを見つけるかもしれないので、私は、同様のMatlabでこれをタグ付けしています。

あなただけのインデックス列と行あなたが好きな方法することができますMATLABで
+0

私はこれを特定の実装に必要とします。しかし、同僚が私に指摘したように、一般的には、まばらな行列に対して順列をしません。まばらな行列「A」は、一般に線形マップ「y = Ax」として使用される。反復ソルバーで。したがって、この交換は、入力ベクトルx(これは 'A 'の列交換)または' y'のエントリ(これは行の交換)のエントリを入れ替えて、 'A'の周りにラッパーを書くことによってより良く実現されます。 – Jan

答えて

4

CSC形式を知ってはいけませんすべてのゼロでないエントリの行インデックスのリストを保持する場合、CSRフォーマットはすべての非ゼロエントリのカラムインデックスのリストを保持します。私はあなたが以下のように周りのものを交換することの利点を取ることができると思うし、私はそれにどんな副作用があってはならないと思う:あなたは今、このような何かを行うことができ

def swap_rows(mat, a, b) : 
    mat_csc = scipy.sparse.csc_matrix(mat) 
    a_idx = np.where(mat_csc.indices == a) 
    b_idx = np.where(mat_csc.indices == b) 
    mat_csc.indices[a_idx] = b 
    mat_csc.indices[b_idx] = a 
    return mat_csc.asformat(mat.format) 

def swap_cols(mat, a, b) : 
    mat_csr = scipy.sparse.csr_matrix(mat) 
    a_idx = np.where(mat_csr.indices == a) 
    b_idx = np.where(mat_csr.indices == b) 
    mat_csr.indices[a_idx] = b 
    mat_csr.indices[b_idx] = a 
    return mat_csr.asformat(mat.format) 

>>> mat = np.zeros((5,5)) 
>>> mat[[1, 2, 3, 3], [0, 2, 2, 4]] = 1 
>>> mat = scipy.sparse.lil_matrix(mat) 
>>> mat.todense() 
matrix([[ 0., 0., 0., 0., 0.], 
     [ 1., 0., 0., 0., 0.], 
     [ 0., 0., 1., 0., 0.], 
     [ 0., 0., 1., 0., 1.], 
     [ 0., 0., 0., 0., 0.]]) 
>>> swap_rows(mat, 1, 3) 
<5x5 sparse matrix of type '<type 'numpy.float64'>' 
    with 4 stored elements in LInked List format> 
>>> swap_rows(mat, 1, 3).todense() 
matrix([[ 0., 0., 0., 0., 0.], 
     [ 0., 0., 1., 0., 1.], 
     [ 0., 0., 1., 0., 0.], 
     [ 1., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 0.]]) 
>>> swap_cols(mat, 0, 4) 
<5x5 sparse matrix of type '<type 'numpy.float64'>' 
    with 4 stored elements in LInked List format> 
>>> swap_cols(mat, 0, 4).todense() 
matrix([[ 0., 0., 0., 0., 0.], 
     [ 0., 0., 0., 0., 1.], 
     [ 0., 0., 1., 0., 0.], 
     [ 1., 0., 1., 0., 0.], 
     [ 0., 0., 0., 0., 0.]]) 

LILマトリックスを使用して、出力のタイプをどのように保持できるかを示しました。アプリケーションでは、既にCSCまたはCSR形式になっていて、変換を最小限に抑えるために、行または列を最初にスワップするかどうかを選択することをお勧めします。

+0

ありがとう@Jaime、これは私が探していたようです。そして、それは私が疎フォーマットにもっと慣れるべきであることを示します。 – Jan

+0

@Janもう少しテストしたいかもしれませんが、すべてのゼロでないエントリが同じであるため、上記の例がうまくいくと思います。私は今は時間がありませんが、それについては後で詳しく見ていきます。別の配列 'mat.indptr'があります。これは変更が必要な場合もあります。 [Yale sparse formatに関するウィキペディアの記事(http://en.wikipedia.org/wiki/Sparse_matrix#Yale_format)は、あなた自身で試してみたい場合に備えて、必要なすべての情報を持っています! – Jaime

+0

私はそれを試して、あなたに知らせるでしょう...ソースに感謝します。 – Jan

0

Matrix = speye(10); 
mycolumnorder = [1 2 3 4 5 6 10 9 8 7]; 
myroworder = [4 3 2 1 5 6 7 8 9 10]; 
Myorderedmatrix = Matrix(myroworder,mycolumnorder); 

私は、これはスパース性を維持すると思うが... ...しかしscipyのダウンロードについて