8

大規模だがまばらな配列があり、行と列を入れ替えて再配置したいと考えています。でこれを行う良い方法は何scipy.sparseですか?

いくつかの問題

  • 順列行列は、スパース構造をランダムに変更するのが好きなので、このタスクには適していないと思います。そして、必要なスワップがほんの少ししかない場合でも、操作は常にすべての列または行を「乗算」します。

  • scipy.sparseこのタスクに最適な疎行列表現は何ですか?

  • 実装に関する提案は大歓迎です。

この質問は必ずしもscipy具体的ではない回答を見つける可能性があるため、これにもMatlabでタグ付けしました。

4

3 に答える 3

5

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 形式になり、それに基づいて行または列を最初に交換するかどうかを選択する必要があります。

于 2013-03-01T16:50:17.593 に答える
0

Matlab では、好きなように列と行にインデックスを付けることができます。

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については知りません...

于 2013-03-01T15:55:21.507 に答える