Python/Scipyではかなり大きな行列を処理します。私は大きな行列(coo_matrixにロードされている)から行を抽出し、それを対角要素として使用する必要があります。現在、私は次のような方法でそれを行う:疎行列の行から疎な対角行列を作成する
import numpy as np
from scipy import sparse
def computation(A):
for i in range(A.shape[0]):
diag_elems = np.array(A[i,:].todense())
ith_diag = sparse.spdiags(diag_elems,0,A.shape[1],A.shape[1], format = "csc")
#...
#create some random matrix
A = (sparse.rand(1000,100000,0.02,format="csc")*5).astype(np.ubyte)
#get timings
profile.run('computation(A)')
私はprofile
出力から見る何diag_elems
を抽出しながら、ほとんどの時間をget_csr_submatrix
機能によって消費されていることです。これは、私が最初のデータの非効率的な疎な表現か、まばらな行列からの行を抽出する間違った方法のどちらかを使用すると考える。疎な行列から行を抽出し、それを斜めの形で表現するより良い方法を提案できますか?
EDIT
は、以下の変異体は、行抽出(csr
に'csc'
を変更するA[i,:]
も同様A.getrow(i)
で交換する必要があり、十分に単純ではないことに注意してください)からボトルネックを除去します。しかし、主な問題は、マテリアライゼーション(.todense()
)を省略し、行の疎な表現から対角行列を作成する方法です。
import numpy as np
from scipy import sparse
def computation(A):
for i in range(A.shape[0]):
diag_elems = np.array(A.getrow(i).todense())
ith_diag = sparse.spdiags(diag_elems,0,A.shape[1],A.shape[1], format = "csc")
#...
#create some random matrix
A = (sparse.rand(1000,100000,0.02,format="csr")*5).astype(np.ubyte)
#get timings
profile.run('computation(A)')
次のように私は、直接1行のCSR行列から対角行列を作成する場合:
diag_elems = A.getrow(i)
ith_diag = sparse.spdiags(diag_elems,0,A.shape[1],A.shape[1])
を、私はformat="csc"
引数を指定することができないどちらも、またith_diags
はCSC形式に変換:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.6/profile.py", line 70, in run
prof = prof.run(statement)
File "/usr/local/lib/python2.6/profile.py", line 456, in run
return self.runctx(cmd, dict, dict)
File "/usr/local/lib/python2.6/profile.py", line 462, in runctx
exec cmd in globals, locals
File "<string>", line 1, in <module>
File "<stdin>", line 4, in computation
File "/usr/local/lib/python2.6/site-packages/scipy/sparse/construct.py", line 56, in spdiags
return dia_matrix((data, diags), shape=(m,n)).asformat(format)
File "/usr/local/lib/python2.6/site-packages/scipy/sparse/base.py", line 211, in asformat
return getattr(self,'to' + format)()
File "/usr/local/lib/python2.6/site-packages/scipy/sparse/dia.py", line 173, in tocsc
return self.tocoo().tocsc()
File "/usr/local/lib/python2.6/site-packages/scipy/sparse/coo.py", line 263, in tocsc
data = np.empty(self.nnz, dtype=upcast(self.dtype))
File "/usr/local/lib/python2.6/site-packages/scipy/sparse/sputils.py", line 47, in upcast
raise TypeError,'no supported conversion for types: %s' % args
TypeError: no supported conversion for types: object`
代わりに 'format =" csr "'を試しましたか? – cyborg
初期データの 'csr'と 'Aget [i、:] 'を' A.getrow(i)'に置き換えて、私は大幅なスピードアップを達成しました。しかし、私が探しているのは、対角行列の作成を行なわないことを実現することを省略することです。何か案は? – savenkov