2017-03-01 8 views
0

私はPythonの初心者です。これはかなり素朴なようです。私はcoo_matrix(scipyのダウンロードスパース行列)Mでの作業とMのトリプレットを返すようにしたいのです:coo_matrix(scipyスパース行列)では、その行の非ゼロインデックスを除く各行で「ランダムな列インデックス」を選択して返す方法はありますか?

row_index,column_index,random_index 

以下の条件で:

  1. ROW_INDEX、column_indexは、非ゼロのエントリを指している必要がありますM
  2. ROW_INDEX、すべての非ゼロエントリに対応column_indexはcolumn_index、ROW_INDEXの各対について
  3. を返さなければならない、random_indexは
  4. を返さなければなりません
  5. random_indexはrandom_indexそのROW_INDEXためのいくつかの非ゼロ点値

私ができるすべての列インデックスの集合であってはならないMの[0、total_num_columns]の範囲内

  • なければなりません次の関数を思い付く:

    def get_triplets(M): 
    return M.row, M.col, np.random.randint(M.shape[1], size=len(M.row)) 
    

    すべてがトリプレットの最後のエントリを除き、上記の関数では正常に動作します - random_indexは、所望の方法ではありません。ランダムなインデックスが、その行の非ゼロインデックスのセットにないことは保証されていません。つまり、条件番号(5)が満たされていない

    上記の5つの条件すべてに合致するトリプレットを返す効率的な方法はありますか?私は自分自身を明確にすることができ、私はクー行列の場合

    おかげ

  • 答えて

    1

    MM.rowM.colM.dataが行列を定義する3つの配列ですが、私の問題を解決する上で任意の助けを感謝し、一緒にすべての非ゼロを識別することを望んでエントリ。それらは順序付けられていなくてもよく、重複を含んでもよい。

    In [1]: from scipy import sparse 
    In [2]: row=[0,0,1,1,1,2,2] 
    In [3]: col=[0,2,0,1,0,1,2] 
    In [4]: data=[1,2,3,4,5,6,7] 
    In [5]: M=sparse.coo_matrix((data,(row,col))) 
    In [6]: M 
    Out[6]: 
    <3x3 sparse matrix of type '<class 'numpy.int32'>' 
        with 7 stored elements in COOrdinate format> 
    In [7]: print(M) 
        (0, 0) 1 
        (0, 2) 2 
        (1, 0) 3 
        (1, 1) 4 
        (1, 0) 5 
        (2, 1) 6 
        (2, 2) 7 
    In [8]: M.A 
    Out[8]: 
    array([[1, 0, 2], 
         [8, 4, 0], 
         [0, 6, 7]]) 
    

    我々はそれが正規作ることができる - と重複することなく並べ替え:

    In [9]: M.sum_duplicates() 
    In [10]: print(M) 
        (0, 0) 1 
        (1, 0) 8 
        (1, 1) 4 
        (2, 1) 6 
        (0, 2) 2 
        (2, 2) 7 
    

    これところで、csrフォーマットへの変換に向かってのステップです。

    (中にエラー - それは最初の列でLEXソートされている)


    私が正しくランダムビットを描く場合、あなたは、各非ゼロエントリのためのゼロスロットからランダムな選択をしたいです同じ行私は、退職者がいるかどうかは気にしないと思います。

    したがって、すべての行をまとめて圧縮する必要があります。 これは単なるMl.rowsに各リストに反復してランダムな選択を生成lil形式

    In [13]: Ml = M.tolil() 
    In [14]: Ml.data 
    Out[14]: array([[1, 2], [8, 4], [6, 7]], dtype=object) 
    In [16]: Ml.rows 
    Out[16]: array([[0, 2], [0, 1], [1, 2]], dtype=object) 
    

    と簡単になります。


    はここでスタートだ:

    def foo(cols, N): 
        c = set(range(N)) 
        c = c.difference(cols) 
        return np.random.choice(list(c)) 
    In [29]: [foo(c,3) for c in Ml.rows] 
    Out[29]: [1, 2, 0] 
    

    ない、非常に私たちが何をしたいです。各行に対してゼロ列を選択します。この例では、行ごとに1つしかありません。呼び出しごとに複数の値を返すために

    変更choice

    def foo(cols, N): 
        c = set(range(N)) 
        c = c.difference(cols) 
        return np.random.choice(list(c),size=len(cols), replace=True) 
    
    In [32]: [foo(c,3) for c in Ml.rows] 
    Out[32]: [array([1, 1]), array([2, 2]), array([0, 0])] 
    

    我々は、これらのランダムな値を取ることができる配列ならば、バックMl

    dataとして
    In [37]: randval = [foo(c,3) for c in Ml.rows] 
    In [38]: randval 
    Out[38]: [array([1, 1]), array([2, 2]), array([0, 0])] 
    In [39]: Ml.data 
    Out[39]: array([[1, 2], [8, 4], [6, 7]], dtype=object) 
    In [40]: Ml.data[:] = randval 
    In [41]: Ml.data 
    Out[41]: array([array([1, 1]), array([2, 2]), array([0, 0])], dtype=object) 
    In [42]: Ml.A 
    Out[42]: 
    array([[1, 0, 1], 
         [2, 2, 0], 
         [0, 0, 0]], dtype=int32) 
    
    In [45]: print(Ml) 
        (0, 0) 1 
        (0, 2) 1 
        (1, 0) 2 
        (1, 1) 2 
        (2, 1) 0 
        (2, 2) 0 
    
    In [48]: Mo=Ml.tocoo() 
    In [51]: np.column_stack((Mo.row, Mo.col, Mo.data)) 
    Out[51]: 
    array([[0, 0, 1], 
         [0, 2, 1], 
         [1, 0, 2], 
         [1, 1, 2], 
         [2, 1, 0], 
         [2, 2, 0]], dtype=int32) 
    

    にそれらを書くこの表示がより有意義になります1行につき複数のゼロ列で大きくなった。また、いずれかの行が密な場合(ゼロ以外)は、私のコードが壊れます。

    だから、すべて一緒にあなたのコメントからコピー

    In [56]: M=sparse.rand(10,10,.2,'coo') 
    In [58]: Ml=M.tolil() 
    In [59]: randval = [foo(c,Ml.shape[1]) for c in Ml.rows] 
    In [61]: Ml.data[:] = randval 
    In [62]: Mo=Ml.tocoo() 
    In [63]: np.column_stack((Mo.row, Mo.col, Mo.data)) 
    

    は、もともと

    のフォーマットを容易にするため、私はこの機能を持っていた:

    def get_triplets(M): 
        return M.row, M.col, np.random.randint(M.shape[1], size=len(M.row)) 
    

    これは時間通りに動作しますが、一貫性がありません。しかし、今:

    def get_triplets(mat): 
        M1 = mat.tolil() 
        randval = [foo(c, M1.shape[1]) for c in M1.rows] 
        M1.data[:] = randval 
        Mo = M1.tocoo() 
        return_mat = np.column_stack((Mo.row, Mo.col, Mo.data)) 
        return return_mat[:, 0], return_mat[:, 1], return_mat[:, 2] 
    
    +1

    ありがとうございました詳細な明確な答えをありがとうございます。 – Learner

    +0

    関数で確認するには:return_mat = np.column_stack((Mo.row、Mo.col、Mo.data))return return_mat [:, 0]、return_mat [:, 1]、return_mat [:, 2] ' – Learner

    +0

    しかし、この操作は非常に時間がかかるようです。あなたが知っているこれを行うための最適な方法はありますか?私は別の質問をするべきですか? – Learner

    関連する問題