2016-10-17 5 views
1

私はCOO形式で格納された疎行列で作業しています。各行ごとに連続する要素の数を取得する最も速い方法は何でしょうか。スパース行列の行の連続する要素

は、たとえば次の行列を考えてみます。

a = [[0,1,2,0],[1,0,0,2],[0,0,0,0],[1,0,1,0]] 

そのCOO表現が

(0, 1) 1 
    (0, 2) 2 
    (1, 0) 1 
    (1, 3) 2 
    (3, 0) 1 
    (3, 2) 1 

私は[1,2,0,2]する結果が必要になります。最初の行には、近くにある2つの非ゼロ要素が含まれています。したがって、そのグループまたはセット。 2番目の行には2つの非ゼロ要素がありますが、近くには存在しません。したがって、2つのグループを形成していると言えます。第3の行には、非ゼロでないのでグループは存在しない。 4番目の行には2つの非ゼロがありますが、ゼロで区切られていないため、2つのグループと見なします。これは1行あたりのクラスタ数に似ています。行を繰り返すことは選択肢ですが、より高速な解決策がない場合に限ります。この点に関する助けに感謝します。

別の簡単な例:次の行を検討:

[1,2,3,0,0,0,2,0,0,8,7,6,0,0] 

上記列が非ゼロはゼロによって分離されたばかりの三つのグループが存在する[3]正弦を返すべきです。

+1

を。 (2)スパース行列がそのために設計されている場合、反復行アプローチは完全です。最初に[csr_matrix]に変換してください(http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix.html#scipy.sparse.csr_matrix)(変換は非常に効率的です! ) – sascha

+0

@saschaただ行内にあるグループの数を見つけること。グループは連続する要素を構成します。質問を更新して明確にする – Stormvirux

答えて

1

高密度アレイに変換し、ロジックを行単位で適用します。

In [623]: M=sparse.coo_matrix(a) 
In [624]: M.data 
Out[624]: array([1, 2, 1, 2, 1, 1]) 
In [625]: M.row 
Out[625]: array([0, 0, 1, 1, 3, 3], dtype=int32) 
In [626]: M.col 
Out[626]: array([1, 2, 0, 3, 0, 2], dtype=int32) 

  • あなたはあなたの行列がどのように見えるcoo形式で
  • 行の繰り返しが速く配列

となっているグループを定義する際に

  • ゼロカウント行あたりのグループの数をしたいです

    この形式では行インデックスが実装されません。 csrlil

    In [627]: M.tolil().data 
    Out[627]: array([[1, 2], [1, 2], [], [1, 1]], dtype=object) 
    In [628]: M.tolil().rows 
    Out[628]: array([[1, 2], [0, 3], [], [0, 2]], dtype=object) 
    

    を行うので、1行のためのまばらな情報は、ゼロ以外のデータ値のリストです[1,2]、およびその列番号、[1,2]のリスト。高密度アレイの列である[0, 1, 2, 0]と比較してください。分析するのは簡単ですか?

    最初の作業は、1つの行を分析する関数を作成することです。私は、密な形が疎な形より優れているかどうかを言うのに十分な論理を研究していません。密集したフォームからカラム情報を取得するのは簡単ですM.A[0,:].nonzero()です。

    In [631]: np.nonzero([1,2,3,0,0,0,2,0,0,8,7,6,0,0]) 
    Out[631]: (array([ 0, 1, 2, 6, 9, 10, 11], dtype=int32),) 
    In [632]: idx=np.nonzero([1,2,3,0,0,0,2,0,0,8,7,6,0,0])[0] 
    In [633]: idx 
    Out[633]: array([ 0, 1, 2, 6, 9, 10, 11], dtype=int32) 
    In [634]: np.diff(idx) 
    Out[634]: array([1, 1, 4, 3, 1, 1], dtype=int32) 
    

    私はより多くの例を見ていると思いますけれども我々は、diff>1数から必要な数を取得することができるかもしれない:あなたの最後の例では

    、私はゼロ以外の指標を得ることができます詳細を定義します。

    複数行への解析の拡張は、最初に完全に単一行の場合を理解することに依存します。のコメント@hpaulj の助けを借りて

  • 0

    私はこれを行うには、次のスニペットを思い付いた:(1)私は例を理解していない

    M = m.tolil() 
    r = [] 
    for i in range(M.shape[0]): 
        sumx=0 
        idx= M.rows[i] 
        if (len(idx) > 2): 
         tempidx = np.diff(idx) 
         if (1 in tempidx): 
          temp = filter(lambda a: a != 1, tempidx) 
          sumx=1 
         counts = len(temp) 
         r.append(counts+sumx) 
        elif (len(idx) == 2): 
         tempidx = np.diff(idx) 
         if(tempidx[0]==1): 
          counts = 1 
          r.append(counts) 
         else: 
          counts = 2 
          r.append(counts) 
        elif (len(idx) == 1): 
         counts = 1 
         r.append(counts) 
        else: 
         counts = 0 
         r.append(counts) 
    tempcluster = np.sum(r)/float(M.shape[0]) 
    cluster.append(tempcluster) 
    
    関連する問題