2014-02-27 8 views
6

Ich versuche, Werte kleiner als 10 von einer sehr großen (1Mx1M) CSR-Matrix (SciPy) zu filtern. Da alle meine Werte ganze Zahlen sind, macht die Division durch 10 und Remultiplizieren um 10 den Job, aber ich frage mich, ob es keinen besseren Weg gibt, um Elemente zu filtern.Filterwerte von einer scipy spärlich Matrix

EDIT: Die Antwort unten funktioniert. Überprüfen Sie, ob Sie die neueste Version von SciPy haben.

+0

Wie funktioniert das? 11/10 * 10 = 10, nicht 11. – wflynny

+0

Nun, für meine spezifische Anwendung ist es gut genug, aber wie gesagt, es sollte eine bessere (d. H. Schnellere und genauere) Art und Weise, dies zu tun, sein. – Omer

Antwort

5

Sie können auch mit dem weniger hacky gehen, aber wahrscheinlich langsamer:

m = m.multiply(m >= 10) 

Um zu verstehen, was los ist:

>>> m = scipy.sparse.csr_matrix((1000, 1000), dtype=np.int) 
>>> m[np.random.randint(0, 1000, 20), 
     np.random.randint(0, 1000, 20)] = np.random.randint(0, 100, 20) 
>>> m.data 
array([92, 46, 99, 24, 75, 16, 49, 60, 87, 64, 91, 37, 30, 32, 25, 40, 99, 
     9, 3, 84]) 
>>> m >= 10 
<1000x1000 sparse matrix of type '<type 'numpy.bool_'>' 
    with 18 stored elements in Compressed Sparse Row format> 
>>> m = m.multiply(m >= 10) 
>>> m 
<1000x1000 sparse matrix of type '<type 'numpy.int32'>' 
    with 18 stored elements in Compressed Sparse Row format> 
>>> m.data 
array([92, 46, 99, 24, 75, 16, 49, 60, 87, 64, 91, 37, 30, 32, 25, 40, 99, 
     84]) 
+0

Ich bin nicht sicher, ob es fair ist, direkte Manipulation der komprimierten Darstellung "hacky" aufzurufen - die Darstellung ist [dokumentiert] (http://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csr_matrix .html), immerhin. –

+0

Bitte, versteh mich nicht falsch, ich denke deine Antwort ist absolut gültig. Deine aktuelle einzige Verbesserung ist meine. ;) Und ich habe Antworten auf spärliche Matrizen, die mit allen drei internen Arrays in schreckliche Komplikationen geraten. Solche Hacky-Manipulationen sind gerechtfertigt, weil "scipy.sparse" sehr viel im Entstehen ist, und mit jeder Veröffentlichung gibt es große Funktionssprünge. Aber solange wir noch nicht da sind, sollte das Ziel schließlich sein, dass es möglich ist, 'm [m <10] = 0 'zu tun, wie man es mit jedem Array machen würde, und damit fertig zu werden. Meine Antwort ist diesem Ideal ein wenig näher, denke ich. – Jaime

+0

Danke Jaime! Ist die Interpretation von (m> = 10) als Matrix ein neues Feature? Es scheint nicht in meiner Version von SciPy zu funktionieren. – Omer

1

Ich denke, die Version Problem hat mit der Umsetzung der zu tun Vergleichsoperatoren. m >= 0, verwendet eine m.__gt__. (Ich habe keine frühere Version von scipy, um das zu testen, aber ich glaube, es gibt einen oder mehrere SO-Threads zum Thema).

Etwas, das in früheren Versionen funktionieren kann, ist:

m.data *= m.data>=10 
m.eliminate_zeros() 

Mit anderen Worten: einen Standard-numpy Betrieb verwenden, um ausgewählte Werte auf 0. Die Test-Set könnte viel komplizierter. Und dann verwenden Sie eine Standard-sparse-Funktion, um es zu bereinigen. Wenn Sie sagen, "filter", was Sie im Wesentlichen tun möchten, ist es nicht: Setzen Sie einige Werte auf Null und entfernen Sie sie aus der Sparse-Matrix?

+0

Bestätigt, das funktioniert mit scipy 0.11.0 – Peter

Verwandte Themen