Wie kann man eine scipy.sparse-Matrix durch eine ausgestrahlte dichte 1d-Array elementweise multiplizieren?

Angenommen, ich habe ein 2d spärliches Array. In meinem echten Gebrauchsfall sind sowohl die Anzahl der Zeilen als auch die Spalten viel größer (sagen wir 20000 und 50000), daher kann es nicht in den Speicher passen, wenn eine dichte Darstellung verwendet wird:

>>> import numpy as np >>> import scipy.sparse as ssp >>> a = ssp.lil_matrix((5, 3)) >>> a[1, 2] = -1 >>> a[4, 1] = 2 >>> a.todense() matrix([[ 0., 0., 0.], [ 0., 0., -1.], [ 0., 0., 0.], [ 0., 0., 0.], [ 0., 2., 0.]]) 

Nun nehme ich an, dass ich ein dichtes 1d Array mit allen Nicht-Nullen Komponenten mit Größe 3 (oder 50000 in meinem echten Leben Fall):

  • Hat Jython die GIL?
  • Python eliminiert Duplikate der Liste mit unerschütterlichen Elementen in einer Zeile
  • Wie man komplette genomsequenz in biopython entrez.forschung herunterlädt
  • Python-Druck-Unicode-Strings in Arrays als Zeichen, nicht Code-Punkte
  • Berechtigung verweigert auf andere App nach makedirs ()
  • Installiere pysvn in einem virtualenv
  •  >>> d = np.ones(3) * 3 >>> d array([ 3., 3., 3.]) 

    Ich möchte die elementare Multiplikation von a und d mit der üblichen Sende-Semantik von numpy berechnen. Allerdings sind spärliche Matrizen in scipy von der np.matrix: der '*' – Operator ist überlastet, um es sich wie ein Matrix-Multiplizieren statt der elementweise-multiplizieren zu verhalten:

     >>> a * d array([ 0., -3., 0., 0., 6.]) 

    Eine Lösung wäre, einen "Umstieg auf die Array-Semantik für den Operator '*' zu machen, das würde das erwartete Ergebnis geben:

     >>> a.toarray() * d array([[ 0., 0., 0.], [ 0., 0., -3.], [ 0., 0., 0.], [ 0., 0., 0.], [ 0., 6., 0.]]) 

    Aber das kann ich nicht machen, da der Aufruf zum toarray () die dichte Version von 'a' materialisieren würde, die nicht in Erinnerung passt (und das Ergebnis wird auch dicht sein):

     >>> ssp.issparse(a.toarray()) False 

    Jede Idee, wie man dies baut, während nur spärliche Datenstrukturen behalten und ohne eine uneffiziente Pythonschleife auf den Spalten von 'a' zu machen?

    3 Solutions collect form web for “Wie kann man eine scipy.sparse-Matrix durch eine ausgestrahlte dichte 1d-Array elementweise multiplizieren?”

    Ich antwortete auch bei scipy.org, aber ich dachte, ich sollte hier eine Antwort hinzufügen, falls andere diese Seite bei der Suche finden.

    Sie können den Vektor in eine spärliche Diagonalmatrix verwandeln und dann Matrixmultiplikation (mit *) verwenden, um das Gleiche wie Rundfunk zu tun, aber effizient.

     >>> d = ssp.lil_matrix((3,3)) >>> d.setdiag(np.ones(3)*3) >>> a*d <5x3 sparse matrix of type '<type 'numpy.float64'>' with 2 stored elements in Compressed Sparse Row format> >>> (a*d).todense() matrix([[ 0., 0., 0.], [ 0., 0., -3.], [ 0., 0., 0.], [ 0., 0., 0.], [ 0., 6., 0.]]) 

    Ich hoffe, das hilft!

    Ich denke, A.multiply (B) sollte in scipy spärlich arbeiten. Die Methode multipliziert "Punkt-weise" Multiplikation, nicht Matrix Multiplikation.

    HTH

    Nun, hier ist ein einfacher Code, der tun wird, was du willst. Ich weiß nicht, ob es so effizient ist, wie Sie es wünschen, also nehmen Sie es oder lassen Sie es:

     import scipy.sparse as ssp def pointmult(a,b): x = a.copy() for i in xrange(a.shape[0]): if x.data[i]: for j in xrange(len(x.data[i])): x.data[i] *= b[x.rows[i]] return x 

    Es funktioniert nur mit lil Matrizen, so dass Sie einige Änderungen vornehmen müssen, wenn Sie möchten, dass es mit anderen Formaten arbeitet.

    Python ist die beste Programmiersprache der Welt.