Przetwarzam raczej duże macierze w języku Python/Scipy. Muszę wyodrębnić wiersze z dużej macierzy (która jest ładowana do coo_matrix) i użyć ich jako przekątnych. Obecnie to zrobić w następujący sposób:Tworzenie rzadkiej macierzy diagonalnej z wiersza rzadkiej macierzy
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)')
Co widzę z wyjścia profile
jest to, że przez większość czasu jest zużywana przez get_csr_submatrix
funkcji podczas wydobywania diag_elems
. To sprawia, że myślę, że używam albo nieefektywnej, rzadkiej reprezentacji początkowych danych, albo niewłaściwego sposobu wyodrębniania wiersza z rzadkiej macierzy. Czy możesz zaproponować lepszy sposób wyodrębnienia wiersza z rzadkiej macierzy i przedstawienia go w przekątnej?
EDIT
Poniżej wariant usuwa gardła z ekstrakcji rzędu (Należy zauważyć, że na łatwą zmianę 'csc'
do csr
nie jest wystarczająca, A[i,:]
należy wymienić A.getrow(i)
również). Jednak głównym pytaniem jest, jak pominąć materializację (.todense()
) i utworzyć przekątną matrycę z rzadkiej reprezentacji wiersza.
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)')
Jeśli tworzę przekątnej matrycy od 1-rzędowym CSR matrycy bezpośrednio, w następujący sposób:
diag_elems = A.getrow(i)
ith_diag = sparse.spdiags(diag_elems,0,A.shape[1],A.shape[1])
wtedy mogę ani określić format="csc"
argumentu, ani konwertować ith_diags
w formacie 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`
wypróbowałeś 'format =" csr "' zamiast? – cyborg
Z "csr" dla danych początkowych i 'A [i,:]' zastąpione 'A.getrow (i)' osiągnąłem znaczne przyspieszenie. Ale to, czego szukam, to pominięcie materializowania tworzenia się diagonalnej macierzy diagonalnej. Jakieś pomysły? – savenkov