2016-07-22 30 views
3

Ich entdeckte ein unerwartetes Verhalten in scipy.sparse.csr_matrix, die ein Fehler für mich scheint. Kann mir jemand bestätigen, dass das nicht normal ist? Ich bin kein Experte für spärliche Strukturen, daher kann ich die korrekte Verwendung missverstehen.Scipy Sparse CSR-Matrix gibt Nan auf 0.0/1.0

>>> import scipy.sparse 
>>> a=scipy.sparse.csr_matrix((1,1)) 
>>> b=scipy.sparse.csr_matrix((1,1)) 
>>> b[0,0]=1 
/home/marco/anaconda3/envs/py35/lib/python3.5/site-packages/scipy/sparse/compressed.py:730: SparseEfficiencyWarning: Changing the sparsity structure of a csr_matrix is expensive. lil_matrix is more efficient. 
    SparseEfficiencyWarning) 
>>> a/b 
matrix([[ nan]]) 

Auf der anderen Seite, Griffe numpy richtig dies:

>>> import numpy as np 
>>> a=np.zeros((1,1)) 
>>> b=np.ones((1,1)) 
>>> a/b 
array([[ 0.]]) 

Dank

+1

Haben Sie versucht mit '(a/b) .toarray()'? –

+0

Sieht für mich wie ein Fehler aus. –

+0

'(a/b) .tolist()' gibt '[[nan]]' zurück. 'a/b' ist vom Typ matrix, also gibt es kein' toarray' oder 'todense'. – marcotama

Antwort

1

Für Sparse Matrix/Sparse Matrix, die

scipy/spärlich/compressed.py

if np.issubdtype(r.dtype, np.inexact): 
     # Eldiv leaves entries outside the combined sparsity 
     # pattern empty, so they must be filled manually. They are 
     # always nan, so that the matrix is completely full. 
     out = np.empty(self.shape, dtype=self.dtype) 
     out.fill(np.nan) 
     r = r.tocoo() 
     out[r.row, r.col] = r.data 
     out = np.matrix(out) 

wird die Aktion in diesem Abschnitt erläutert.

dieses Versuchen mit etwas größeren Matrizen

In [69]: a=sparse.csr_matrix([[1.,0],[0,1]]) 
In [70]: b=sparse.csr_matrix([[1.,1],[0,1]]) 
In [72]: (a/b) 
Out[72]: 
matrix([[ 1., nan], 
     [ nan, 1.]]) 

Also wo immer a 0s (keine Sparse-Werte) hat, ist die Aufteilung nan. Es gibt eine dichte Matrix zurück und füllt nan aus.

Ohne diesen Code erzeugt die spärliche Element-für-Element-Division eine spärliche Matrix mit diesen "leeren" Off-Diagonal-Slots.

In [73]: a._binopt(b,'_eldiv_') 
Out[73]: 
<2x2 sparse matrix of type '<class 'numpy.float64'>' 
    with 2 stored elements in Compressed Sparse Row format> 
In [74]: a._binopt(b,'_eldiv_').A 
Out[74]: 
array([[ 1., 0.], 
     [ 0., 1.]]) 

Die inverse könnte

In [76]: b/a 
Out[76]: 
matrix([[ 1., inf], 
     [ nan, 1.]]) 
In [77]: b._binopt(a,'_eldiv_').A 
Out[77]: 
array([[ 1., inf], 
     [ 0., 1.]]) 

Es sieht aus wie die combined sparsity pattern durch den Zähler bestimmt wird aufschlussreich sein. Im weiteren Test sieht das nach eliminate_zeros aus.

In [138]: a1=sparse.csr_matrix(np.ones((2,2))) 
In [139]: a1 
Out[139]: 
<2x2 sparse matrix of type '<class 'numpy.float64'>' 
    with 4 stored elements in Compressed Sparse Row format> 
In [140]: a1[0,1]=0 
In [141]: a1 
Out[141]: 
<2x2 sparse matrix of type '<class 'numpy.float64'>' 
    with 4 stored elements in Compressed Sparse Row format> 
In [142]: a1/b 
Out[142]: 
matrix([[ 1., nan], 
     [ inf, 1.]]) 
+0

Ja, das ist die Ursache des Fehlers. Ich habe hier einen Fix gesendet: https://github.com/scipy/scipy/pull/6405 – perimosocordiae

Verwandte Themen