2017-07-12 23 views
1

この作業はとてもPythonでスパース行列をスパース行列に追加するには?

import numpy as np 

a= np.array([[1,2,3,0,9],[3,2,6,2,7],[0,0,0,8,0],[1,0,0,0,3]]) 
a + a[1] 

出力のようnumpyのに非常に簡単である:

array([[ 4, 4, 9, 2, 16], 
     [ 6, 4, 12, 4, 14], 
     [ 3, 2, 6, 10, 7], 
     [ 4, 2, 6, 2, 10]]) 

は、ベクトルの大きさが自動的に行列の各列にブロードキャストする方法を参照してください。

しかし、スパース行列については、ディメンションの不一致エラーがあります。

from scipy.sparse import * 

a= csr_matrix([[1,2,3,0,9],[3,2,6,2,7],[0,0,0,8,0],[1,0,0,0,3]]) 
a + a[1] 

出力:

--------------------------------------------------------------------------- 
ValueError        Traceback (most recent call last) 
<ipython-input-32-74c48fe5106e> in <module>() 
     2 
     3 a= csr_matrix([[1,2,3,0,9],[3,2,6,2,7],[0,0,0,8,0],[1,0,0,0,3]]) 
----> 4 a + a[1] 

/opt/anaconda2/lib/python2.7/site-packages/scipy/sparse/compressed.pyc in __add__(self, other) 
    337   elif isspmatrix(other): 
    338    if (other.shape != self.shape): 
--> 339     raise ValueError("inconsistent shapes") 
    340 
    341    return self._binopt(other,'_plus_') 

ValueError: inconsistent shapes 

ありスパース乗算のための関数であり、(完全にその仕事をしていません)a * a[1]ため、例えば、a.multiply(a[1])が、私は追加のための1つを見つけることができませんでした。

スパース行列が新しくなりました。助けてください。

答えて

0

することで試してみてください:

from scipy.sparse import * 

a= csr_matrix([[1,2,3,0,9],[3,2,6,2,7],[0,0,0,8,0],[1,0,0,0,3]]) 
a.todense()+a[1].todense() 

それは次のようになります。

matrix([[ 4, 4, 9, 2, 16], 
     [ 6, 4, 12, 4, 14], 
     [ 3, 2, 6, 10, 7], 
     [ 4, 2, 6, 2, 10]]) 

更新:

同じ次元とa[1]との完全なと付加行列bを行い、その後、それらを追加します。

from scipy.sparse import * 
import numpy as np 
an_array=np.array([[1,2,3,0,9],[3,2,6,2,7],[0,0,0,8,0],[1,0,0,0,3]]) 
a = csr_matrix(an_array) 
b = csr_matrix([an_array[1] for i in range(len(an_array))]) 
a+b 
+3

密な表現に変換することは、明らかな(良い)解決策になります。ただし、上記の例はMWEだけです。私たちは構造が僅かしかなくても巨大な行列の場合には、疎な行列に行きます。単一の操作のためにそれらを密な形に変換すると、その目的を破るでしょう(その場合、最初からNumPyに固執する方が良いでしょう)。 –

+0

多分、同じ次元のすべての値が 'a [1]'から来た疎な行列を作ることができます。 –

2

numpyスパース行列に対しては、スタイルブロードキャストが実装されていません。

乗算、特に行列乗算がよく開発されています。実際、行の合計や行の選択などのアクションは、行列乗算として実装されています。 M * <column vector of 1s>。乗算を行うと、そうでなくても疎な行列が得られることがよくあります。

加減算がうまくいきません。しばしば密度の高いマトリックスが得られます。極端な場合は、すべての要素にスカラーを追加することです。あなたの例でさえ、結果は密である。 aa[1,:]の両方は、まばらな純粋な追加を正当化するにはまばらでなければなりません。

In [713]: a= np.array([[1,2,3,0,9],[3,2,6,2,7],[0,0,0,8,0],[1,0,0,0,3]]) 
In [714]: aM = sparse.csr_matrix(a) 
In [715]: aM 
Out[715]: 
<4x5 sparse matrix of type '<class 'numpy.int32'>' 
    with 12 stored elements in Compressed Sparse Row format> 

我々は、行列乗算によって選択された行を複製することができる - 最初放送密なアプローチ:

In [719]: np.ones((4,1))*aM[1,:] 
Out[719]: 
array([[ 3., 2., 6., 2., 7.], 
     [ 3., 2., 6., 2., 7.], 
     [ 3., 2., 6., 2., 7.], 
     [ 3., 2., 6., 2., 7.]]) 
In [720]: np.ones((4,1))*aM[1,:]+aM # dense matrix addition 
Out[720]: 
matrix([[ 4., 4., 9., 2., 16.], 
     [ 6., 4., 12., 4., 14.], 
     [ 3., 2., 6., 10., 7.], 
     [ 4., 2., 6., 2., 10.]]) 

疎行列乗算:

In [721]: sparse.csr_matrix(np.ones((4,1)))*aM[1,:] 
Out[721]: 
<4x5 sparse matrix of type '<class 'numpy.float64'>' 
    with 20 stored elements in Compressed Sparse Row format> 

疎行列添加:

In [722]: sparse.csr_matrix(np.ones((4,1)))*aM[1,:]+aM 
Out[722]: 
<4x5 sparse matrix of type '<class 'numpy.float64'>' 
    with 20 stored elements in Compressed Sparse Row format> 
In [723]: _.A 
Out[723]: 
array([[ 4., 4., 9., 2., 16.], 
     [ 6., 4., 12., 4., 14.], 
     [ 3., 2., 6., 10., 7.], 
     [ 4., 2., 6., 2., 10.]]) 

これは、aM、特にaM[1:]がまばらだった場合のより良いデモンストレーションになります。またnp.onesint dtypeと指定して、aMと一致させることもできます。そしてそれをcsc行列にすることはよりコンパクトになるでしょう。

+0

かなり便利です。私はいつもLine-722のような文が同じエラーを投げると思っていました。それで、なぜSciPyに最適化されたスパースベクトル加算が含まれていたのですが、まともなベクトル乗算ルーチンを持っていませんでしたか? –

+0

[722]では、同じ形の2つの行列を追加しています。要素単位の加算は、要素単位の乗算よりも単なる作業です。 'a [i、j]'または 'b [i、j]'が加算時に0以外の場合、 'c [i、j]'は非ゼロになります。乗算すると、どちらかがゼロの場合、 'c [i、j]'をスキップできます。 – hpaulj

+0

'csr_matrix.multiply'のドキュメントを探します。 [ソース]をクリックすると、ファイルと計算が実装されているファイル、または少なくともPythonの部分が表示されます。ハードワークはコンパイルされたコードで行われます。 – hpaulj

関連する問題