2017-10-23 4 views
1

Ich habe eine scipy spärliche Matrix data und eine ganze Zahl n, die einer Zeile in data entspricht, die ich löschen möchte. Um diese Zeile zu löschen habe ich versucht, dieses:Zeile aus Scipy-Matrix löschen

data = sparse.csr_matrix(np.delete(np.array(data),n, axis=0)) 

Dies ist jedoch diesen Fehler erzeugt hat:

Traceback (most recent call last): 
    File "...", line 260, in <module> 
    X_labeled = sparse.csr_matrix(np.delete(np.array(X_labeled),n, axis=0)) 
    File "/anaconda3/lib/python3.6/site-packages/scipy/sparse/compressed.py", line 79, in __init__ 
    self._set_self(self.__class__(coo_matrix(arg1, dtype=dtype))) 
    File "/anaconda3/lib/python3.6/site-packages/scipy/sparse/coo.py", line 177, in __init__ 
    self.row, self.col = M.nonzero() 
SystemError: <built-in method nonzero of numpy.ndarray object at 0x113c883f0> returned a result with an error set 

Wenn ich laufen:

data = np.delete(data.toarray(),n, axis=0) 

ich diesen Fehler:

Traceback (most recent call last): 
    File "...", line 261, in <module> 
    X_labeled = np.delete(X_labeled.toarray(),n, axis=0) 
    File "/anaconda3/lib/python3.6/site-packages/numpy/lib/function_base.py", line 4839, in delete 
    "size %i" % (obj, axis, N)) 
IndexError: index 86 is out of bounds for axis 0 with size 4 

Wenn ich dies ausführen:

print(type(data)) 
print(data.shape) 
print(data.toarray().shape) 

ich dieses:

<class 'scipy.sparse.csr.csr_matrix'> 
(4, 2740) 
(4, 2740) 
+0

Was macht Sie Daten aus? Das Ausführen dieser Zeile mit diesen einfachen Daten funktioniert: 'data = np.array ([1, 2, 3, 4, 5, 6])'. –

+0

Der richtige Weg, um eine dünn besiedelte Matrix in ein dichtes Array zu verwandeln, ist 'data.toarray()' – hpaulj

+0

Warum indexieren Sie 'data' nicht mit allen Zeilenindizes außer demjenigen, der gelöscht werden soll? – hpaulj

Antwort

1

Der richtige Weg, um eine Sparse Matrix in ein dichtes zu verwandeln ist mit toarray, nicht np.array(...):

In [408]: M = sparse.csr_matrix(np.eye(3)) 
In [409]: M 
Out[409]: 
<3x3 sparse matrix of type '<class 'numpy.float64'>' 
    with 3 stored elements in Compressed Sparse Row format> 
In [410]: np.array(M) 
Out[410]: 
array(<3x3 sparse matrix of type '<class 'numpy.float64'>' 
    with 3 stored elements in Compressed Sparse Row format>, dtype=object) 

Dies ist ein einzelnes Element Objekt dtype-Array, das die Sparse-Matrix enthält - unverändert.

In [411]: M.toarray() 
Out[411]: 
array([[ 1., 0., 0.], 
     [ 0., 1., 0.], 
     [ 0., 0., 1.]]) 

delete Arbeiten mit diesem richtigen Array:

In [414]: data = sparse.csr_matrix(np.delete(M.toarray(),1, axis=0)) 
In [415]: data 
Out[415]: 
<2x3 sparse matrix of type '<class 'numpy.float64'>' 
    with 2 stored elements in Compressed Sparse Row format> 
In [416]: data.A 
Out[416]: 
array([[ 1., 0., 0.], 
     [ 0., 0., 1.]]) 

Indexierung wird das gleiche tun:

In [417]: M[[0,2],:] 
Out[417]: 
<2x3 sparse matrix of type '<class 'numpy.float64'>' 
    with 2 stored elements in Compressed Sparse Row format> 
In [418]: _.A 
Out[418]: 
array([[ 1., 0., 0.], 
     [ 0., 0., 1.]]) 
In [420]: M[np.array([True,False,True]),:].A 
Out[420]: 
array([[ 1., 0., 0.], 
     [ 0., 0., 1.]]) 

Ich würde vermuten, dass die Indizierung Strecke schneller ist, aber wir würden haben Zeittests auf realistischen Größen-Arrays zu machen, um sicher zu sein.

Intern ist delete ziemlich komplex, aber für einige Eingaben macht es etwas wie das Erstellen eines booleschen Arrays mit False für die Zeilen, die Sie löschen möchten.


Herstellung der boolean Maske:

In [421]: mask=np.ones((3,),bool) 
In [422]: mask[1]=False 
In [423]: M[mask,:].A 
+0

Ich denke, du meinst 'todense()' Methode .. ah vergiss es geht nicht um Matrizen sowieso – percusse

+0

'todense' macht eine' np.matrix', 'toarray' macht ein' np.darray' (mit einem '.A' kurz Schnitt). – hpaulj