Ersatz für numpy broadcasting mit scipy.sparse.csc_matrix

Ich habe in meinem Code den folgenden Ausdruck:

a = (b / x[:, np.newaxis]).sum(axis=1) 

Wo b ein ndarray der Form (M, N) ist und x ein ndarray der Form (M,) . Nun, b ist eigentlich spärlich, also für die Speicher-Effizienz möchte ich in einem scipy.sparse.csc_matrix oder csr_matrix . Allerdings ist die Ausstrahlung auf diese Weise nicht implementiert (auch wenn Division oder Multiplikation garantiert Sparsity beibehalten) (die Einträge von x sind ungleich Null) und hebt einen NotImplementedError . Gibt es eine sparse Funktion, die mir nicht bewusst ist, würde das tun, was ich will? ( dot() würde die falsche Achse zusammenfassen.)

2 Solutions collect form web for “Ersatz für numpy broadcasting mit scipy.sparse.csc_matrix”

Wenn b im CSC-Format ist, dann hat b.data die Nicht-Null-Einträge von b und b.indices hat den Zeilenindex von jedem der Nicht-Null-Einträge, so können Sie Ihre Division als:

 b.data /= np.take(x, b.indices) 

Es ist hacker als Warrens elegante Lösung, aber es wird wohl auch in den meisten Einstellungen schneller sein:

 b = sps.rand(1000, 1000, density=0.01, format='csc') x = np.random.rand(1000) def row_divide_col_reduce(b, x): data = b.data.copy() / np.take(x, b.indices) ret = sps.csc_matrix((data, b.indices.copy(), b.indptr.copy()), shape=b.shape) return ret.sum(axis=1) def row_divide_col_reduce_bis(b, x): d = sps.spdiags(1.0/x, 0, len(x), len(x)) return (d * b).sum(axis=1) In [2]: %timeit row_divide_col_reduce(b, x) 1000 loops, best of 3: 210 us per loop In [3]: %timeit row_divide_col_reduce_bis(b, x) 1000 loops, best of 3: 697 us per loop In [4]: np.allclose(row_divide_col_reduce(b, x), ...: row_divide_col_reduce_bis(b, x)) Out[4]: True 

Sie können die Zeit fast halb im obigen Beispiel schneiden, wenn Sie die Teilung an Ort und Stelle machen, dh:

 def row_divide_col_reduce(b, x): b.data /= np.take(x, b.indices) return b.sum(axis=1) In [2]: %timeit row_divide_col_reduce(b, x) 10000 loops, best of 3: 131 us per loop 

Um a = (b / x[:, np.newaxis]).sum(axis=1) zu implementieren, kannst du a = b.sum(axis=1).A1 / x . Das A1 Attribut gibt das 1D ndarray zurück, also ist das Ergebnis ein 1D ndarray, keine matrix . Dieser prägnante Ausdruck funktioniert, weil man beide durch x skaliert und entlang der Achse 1 summiert. Zum Beispiel:

 In [190]: b Out[190]: <3x3 sparse matrix of type '<type 'numpy.float64'>' with 5 stored elements in Compressed Sparse Row format> In [191]: bA Out[191]: array([[ 1., 0., 2.], [ 0., 3., 0.], [ 4., 0., 5.]]) In [192]: x Out[192]: array([ 2., 3., 4.]) In [193]: b.sum(axis=1).A1 / x Out[193]: array([ 1.5 , 1. , 2.25]) 

Im Allgemeinen, wenn man die Zeilen einer spärlichen Matrix mit einem Vektor x skalieren möchte, könnte man b auf der linken Seite mit einer spärlichen Matrix, die 1.0/x auf der Diagonale enthält, multiplizieren. Die Funktion scipy.sparse.spdiags kann verwendet werden, um eine solche Matrix zu erstellen. Beispielsweise:

 In [71]: from scipy.sparse import csc_matrix, spdiags In [72]: b = csc_matrix([[1,0,2],[0,3,0],[4,0,5]], dtype=np.float64) In [73]: bA Out[73]: array([[ 1., 0., 2.], [ 0., 3., 0.], [ 4., 0., 5.]]) In [74]: x = array([2., 3., 4.]) In [75]: d = spdiags(1.0/x, 0, len(x), len(x)) In [76]: dA Out[76]: array([[ 0.5 , 0. , 0. ], [ 0. , 0.33333333, 0. ], [ 0. , 0. , 0.25 ]]) In [77]: p = d * b In [78]: pA Out[78]: array([[ 0.5 , 0. , 1. ], [ 0. , 1. , 0. ], [ 1. , 0. , 1.25]]) In [79]: a = p.sum(axis=1) In [80]: a Out[80]: matrix([[ 1.5 ], [ 1. ], [ 2.25]]) 
  • 2D-Array, um eine riesige Python-Dikt darzustellen, COOrdinate wie Lösung, um Speicher zu sparen
  • Füllen Sie einen Pandas SparseDataFrame aus einer SciPy Sparse Matrix
  • Zugriffswert, Spaltenindex und row_ptr Daten aus scipy CSR Sparse Matrix
  • Effizientes Sammeln einer Sammlung von spärlichen scipy Matrizen
  • Umformung spärlicher Matrix effizient, Python, SciPy 0.12
  • Berechnen Sie die Untermenge der Matrixmultiplikation
  • Putting Spalte in leere Sparse Matrix
  • Effizientes Aufschneiden von Matrizen mittels Matrixmultiplikation mit Python, NumPy, SciPy
  • Sqrt für elementweise spärliche Matrix
  • Spärliche Matrix-LP-Probleme in Gurobi / Python
  • Markov Kette stationäre Verteilungen mit scipy.sparse?
  • Python ist die beste Programmiersprache der Welt.