2016-12-11 18 views
1

Sは大きなscipy-csr-matrix(疎)であり、key-> index(位置)の辞書Dです。 S &の行ベクトルA values - > Sの他の行ベクトルlのすべてのインデックス(位置)のリストlの各行ベクトルに対して、Aを減算して新しいベクトルを得る。新しいスパース行列で更新されます。フォームのPythonで与えられた大きな疎行列の異なる行の操作から新しい疎行列を作成する

辞書 - > {1:[4,5、...、63]}次に で新しいスパース行列を作成する必要が....

new_row_vector_1 - > S_vec - S_vec

new_row_vector_2 - > S_vec - S_vec

new_row_vector_n - > S_vec - S_vec S_​​vecXが

Check out the pictorial explanation of the above statements

numpyの例行列SのX番目の行ベクトルである

>>> import numpy as np 
>>> s = np.array([[1,5,3,4],[3,0,12,7],[5,6,2,4],[4,6,6,4],[7,12,5,67]]) 
>>> s 
array([[ 1, 5, 3, 4], 
     [ 3, 0, 12, 7], 
     [ 5, 6, 2, 4], 
     [ 4, 6, 6, 4], 
     [ 7, 12, 5, 67]]) 
>>> index_dictionary = {0: [2, 4], 1: [3, 4], 2: [1], 3: [1, 2], 4: [1, 3, 2]} 
>>> n = np.zeros((10,4)) #sum of all lengths of values in index_dictionary would be the number of rows for the new array(n) and columns remain the same as s. 
>>> n 
array([[ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.], 
     [ 0., 0., 0., 0.]]) 
>>> idx = 0 
>>> for index in index_dictionary: 
...  for k in index_dictionary[index]: 
...    n[idx] = s[index]-s[k] 
...    idx += 1 
... 
>>> n 
array([[ -4., -1., 1., 0.], 
     [ -6., -7., -2., -63.], 
     [ -1., -6., 6., 3.], 
     [ -4., -12., 7., -60.], 
     [ 2., 6., -10., -3.], 
     [ 1., 6., -6., -3.], 
     [ -1., 0., 4., 0.], 
     [ 4., 12., -7., 60.], 
     [ 3., 6., -1., 63.], 
     [ 2., 6., 3., 63.]]) 

N私が欲しいものです。

まずnumpyの配列バージョン:今

In [619]: arr=np.arange(12).reshape(4,3) 
In [620]: arr[[1,0,2,3]]-arr[0] 
Out[620]: 
array([[3, 3, 3], 
     [0, 0, 0], 
     [6, 6, 6], 
     [9, 9, 9]]) 

スパース同等:

+0

あなたは小さな定期 'numpy'配列でこれを行うだろう方法を示します。良い例では、スパース行列に特別な処理が必要かどうかを心配することができます。 – hpaulj

+0

コメントありがとうございます。確認してください、numpyの配列の場合に私たちがそれを行う方法についての例を加えました。 – xlax

+0

これを幾分高いレベルとして必要とする理由についていくつかの文脈を教えてください。私の直感は、少し問題を再考することによって、それがはるかに優雅にnumpyの操作にマッピングされるかもしれないということです。 –

答えて

0

は、ここで私はあなたがやろうとしていると思うかの簡単なデモです

In [622]: M=sparse.csr_matrix(arr) 

csrは、行を実装しますインデックス:

In [624]: M[[1,0,2,3]] 
Out[624]: 
<4x3 sparse matrix of type '<class 'numpy.int32'>' 
    with 11 stored elements in Compressed Sparse Row format> 
In [625]: M[[1,0,2,3]].A 
Out[625]: 
array([[ 3, 4, 5], 
     [ 0, 1, 2], 
     [ 6, 7, 8], 
     [ 9, 10, 11]], dtype=int32) 

しかしない放送:

In [626]: M[[1,0,2,3]]-M[0] 
.... 
ValueError: inconsistent shapes 

をだから私たちはこれが最速または最も効率的ではないかもしれないが、それはスタートだ

In [627]: M[[1,0,2,3]]-M[[0,0,0,0]] # or M[[0]*4] 
Out[627]: 
<4x3 sparse matrix of type '<class 'numpy.int32'>' 
    with 9 stored elements in Compressed Sparse Row format> 
In [628]: _.A 
Out[628]: 
array([[3, 3, 3], 
     [0, 0, 0], 
     [6, 6, 6], 
     [9, 9, 9]], dtype=int32) 

放送の明示的なフォームを使用することができます。

私はSO M[[1,0,2,3]]インデックスは、このケースでの同等の、行列の乗算で実行されていることに疑問以前で見つかった:

idxM = sparse.csr_matrix(([1,1,1,1],([0,1,2,3],[1,0,2,3])),(4,4)) 
M1 = idxM * M 

Sparse matrix slicing using list of int

は、だから私の差分式はと一緒に2、そのような乗算を必要とし減算。

行の反復処理を試して結果から新しい行列を作成することもできますが、それが高速になるという保証はありません。配列に応じて、高密度に変換することも早く変換することも可能です。

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

私は辞書にこれを適用する2つの方法を想像することができます。

一つは、辞書を反復処理(どのような順序?)、各キーのため、この違いを行い、リスト内の結果を収集(スパース行列のリスト)、および1つのマトリックスにそれらを結合するためにsparse.bmatを使用することです。

もう1つは、インデックスの2つのリストを収集し、上記のインデックス付き差分を1回だけ適用することです。

あなたの密集 sに適用
In [8]: index_dictionary = {0: [2, 4], 1: [3, 4], 2: [1], 3: [1, 2], 4: [1, 3, 2]} 
In [10]: alist=[] 
    ...: for index in index_dictionary: 
    ...:  for k in index_dictionary[index]: 
    ...:   alist.append((index, k))  
In [11]: idx = np.array(alist) 
In [12]: idx 
Out[12]: 
array([[0, 2], 
     [0, 4], 
     [1, 3], 
     [1, 4], 
     [2, 1], 
     [3, 1], 
     [3, 2], 
     [4, 1], 
     [4, 3], 
     [4, 2]]) 

In [15]: s = np.array([[1,5,3,4],[3,0,12,7],[5,6,2,4],[4,6,6,4],[7,12,5,67]]) 
In [16]: s[idx[:,0]]-s[idx[:,1]] 
Out[16]: 
array([[ -4, -1, 1, 0], 
     [ -6, -7, -2, -63], 
     [ -1, -6, 6, 3], 
     [ -4, -12, 7, -60], 
     [ 2, 6, -10, -3], 
     [ 1, 6, -6, -3], 
     [ -1, 0, 4, 0], 
     [ 4, 12, -7, 60], 
     [ 3, 6, -1, 63], 
     [ 2, 6, 3, 63]]) 

とスパース同等に

In [19]: arr= sparse.csr_matrix(s) 
In [20]: arr 
Out[20]: 
<5x4 sparse matrix of type '<class 'numpy.int32'>' 
    with 19 stored elements in Compressed Sparse Row format> 
In [21]: res=arr[idx[:,0]]-arr[idx[:,1]] 
In [22]: res 
Out[22]: 
<10x4 sparse matrix of type '<class 'numpy.int32'>' 
    with 37 stored elements in Compressed Sparse Row format> 
+0

これは完璧です!ありがとう:) – xlax