2016-10-29 26 views
0

単純なベクトル行列の乗算では、密行列の代わりにscipy.sparse行列を使用すると、異なる結果/出力形式が得られます。私は、次の予想される出力を得るベクトル行列積について疎と密行列間のベクトル行列積の差

import numpy as np 
from scipy import sparse 
mat = np.array([[1, 1, 0, 0, 0], [0, 2, 2, 0, 0], [0, 0, 3, 3, 0], [0, 0, 0, 4, 4]]) 
vec = np.arange(1, 5) 

:私は、次の密行列とベクトルを使用する例として

vec.dot(mat) # array([ 1, 5, 13, 25, 16]) 
mat.T.dot(vec) # array([ 1, 5, 13, 25, 16]) 
mat.T.dot(vec.T) # array([ 1, 5, 13, 25, 16]) 

を私がベクトルならば、それは役割を果たしていないことを受け入れます転置されているか否か。私は疎行列mat_sparseによってマトリックスmatを交換する場合には、私は入手転置行列のトリックを使用して、すなわち[1x mat_sparse, 2x mat_sparse, ...]

mat_sparse = sparse.lil_matrix(mat) 
vec.dot(mat_sparse) # array([ <4x5 sparse matrix of type '<type 'numpy.int64'>' with 8 stored elements in LInked List format>, ...], dtype=object) 

、結果として、各ベクトル成分を乗じ疎行列を含むスパース4×5の行列のアレイを得ます期待される結果:

mat_sparse.T.dot(vec4.T) # array([ 1, 5, 13, 25, 16]) 

誰かがこの動作が期待される理由を説明できますか?行列mat(実際には2次元配列)をnp.matrix(matのインスタンスに置き換えても、結果は変更されません。

答えて

0

一般的に、numpyの関数とメソッドはスパース行列で正しく動作するとは考えていません。スパースメソッドと関数を使用する方が良いです。通常のnumpyコードは、疎行列については何も知らない。

マトリックス(スパースまたはnp.matrix)では、*が行列乗算です。この文脈において

In [2150]: vec*smat # smat=csr_matrix(mat) 
Out[2150]: array([ 1, 5, 13, 25, 16], dtype=int32) 

*の疎行列定義が優先されます。この式で

In [2151]: vec.dot(smat) 
Out[2151]:... 
array([ <4x5 sparse matrix of type '<class 'numpy.int32'>' 
    with 8 stored elements in Compressed Sparse Row format>, 
    ... 
    with 8 stored elements in Compressed Sparse Row format>], dtype=object) 

vec.dotは疎行列については何も知りません。それはの各行で別々にdotを実行しているように見えますが、さらに掘り下げなければなりません。その*として

次作品を、それがdotのまばらな定義を使用しているため、同じ:

In [2163]: smat.T.dot(vec) 
Out[2163]: array([ 1, 5, 13, 25, 16], dtype=int32) 

np.dotは、スパース行列の限られた理解を持っています。たとえば、両方の引数が疎である場合に機能します。 (np.dot(mat, mat.T)と同じ)np.dot(smat, smat.T)作品

In [2177]: np.dot(smat.T,sparse.csr_matrix(vec).T).A 
Out[2177]: 
array([[ 1], 
     [ 5], 
     [13], 
     [25], 
     [16]], dtype=int32) 

それはどのように作成されるか、スパース行列をよく読んで、そのデータを保存するのを助けることができます。それらはnp.ndarrayのサブクラスではありません。

0

sparse行列の演算結果は、しばしばsparse行列になります。

密度の高い行列に戻したい場合は、結果に.toarray()メソッドを使用して質問する必要があります。

+0

配列を行列で置き換えるとき、つまり 'mat2 = np.matrix(np。配列([[1,1,0,0,0]、[0,2,2,0,0]、[0,0,3,3,0]、[0,0,0,4,4] ])) '私は' matrix([[1,5、13、25、16]]) 'を得る。だから私はスパース行列を使用するときにスパース行列を得ることを期待しますが、代わりにスパース行列の配列を取得します。 私は約50000 x 50000のスパース行列を使うので、 'todense()'を使うことはできません。 – murban