Pandas spärliche DatenFrame zur spärlichen Matrix, ohne eine dichte Matrix im Speicher zu erzeugen

Gibt es eine Möglichkeit, von einem pandas.SparseDataFrame zu pandas.SparseDataFrame zu scipy.sparse.csr_matrix , ohne eine dichte Matrix im Speicher zu erzeugen?

 scipy.sparse.csr_matrix(df.values) 

Funktioniert nicht, da es eine dichte Matrix erzeugt, die in die csr_matrix gegossen csr_matrix .

Danke im Voraus!

  • Effiziente inkrementelle spärliche Matrix in Python / Scipy / Numpy
  • Aufbau und Aktualisierung einer spärlichen Matrix in Python mit scipy
  • Mit scipy spärlichen Matrizen, um System von Gleichungen zu lösen
  • Python matplotlib plot spärliches matrixmuster
  • 2D-Array, um eine riesige Python-Dikt darzustellen, COOrdinate wie Lösung, um Speicher zu sparen
  • Durchführen von PCA auf großer spärlicher Matrix unter Verwendung von sklearn
  • Numpy Matrix Produkt - spärliche Matrizen
  • Berechnen von N kleinsten Eigenwerten von Sparse Matrix in Python
  • 5 Solutions collect form web for “Pandas spärliche DatenFrame zur spärlichen Matrix, ohne eine dichte Matrix im Speicher zu erzeugen”

    Pandas docs spricht über eine experimentelle Umwandlung zu scipy spärlich, SparseSeries.to_coo:

    http://pandas-docs.github.io/pandas-docs-travis/sparse.html#interaction-with-scipy-sparse

    ================

    Edit – das ist eine spezielle Funktion aus einem Multiindex, kein Datenrahmen. Sehen Sie die anderen Antworten dafür. Beachten Sie den Unterschied in den Daten.

    Auf der Antwort von Victor May ist hier eine etwas schnellere Implementierung, aber es funktioniert nur, wenn das gesamte SparseDataFrame mit allen BlockIndex spärlich ist (Hinweis: Wenn es mit get_dummies , wird dies der Fall sein).

    Edit : Ich habe dies geändert, damit es mit einem Nicht-Null-Füllwert arbeiten wird. CSR hat keinen nativen Nicht-Null-Füllwert, also musst du ihn extern aufnehmen.

     import numpy as np import pandas as pd from scipy import sparse def sparse_BlockIndex_df_to_csr(df): columns=df.columns data,rows=map(list,zip(*[(df[col].sp_values-df[col].fill_value,df[col].sp_index.to_int_index().indices) for col in columns])) cols=[np.ones_like(a)*i for (i,a) in enumerate(data)] data_f = np.concatenate(data) rows_f = np.concatenate(rows) cols_f = np.concatenate(cols) arr = sparse.coo_matrix((data_f, (rows_f, cols_f)), df.shape, dtype=np.float64) return arr.tocsr() 

    Die Antwort von @Marigold macht den Trick, aber es ist langsam durch den Zugriff auf alle Elemente in jeder Spalte, einschließlich der Nullen. Auf dieser Seite schrieb ich den folgenden schnellen n 'schmutzigen Code, der etwa 50x schneller auf einer 1000×1000 Matrix mit einer Dichte von etwa 1% läuft. Mein Code behandelt auch dichte Spalten entsprechend.

     def sparse_df_to_array(df): num_rows = df.shape[0] data = [] row = [] col = [] for i, col_name in enumerate(df.columns): if isinstance(df[col_name], pd.SparseSeries): column_index = df[col_name].sp_index if isinstance(column_index, BlockIndex): column_index = column_index.to_int_index() ix = column_index.indices data.append(df[col_name].sp_values) row.append(ix) col.append(len(df[col_name].sp_values) * [i]) else: data.append(df[col_name].values) row.append(np.array(range(0, num_rows))) col.append(np.array(num_rows * [i])) data_f = np.concatenate(data) row_f = np.concatenate(row) col_f = np.concatenate(col) arr = coo_matrix((data_f, (row_f, col_f)), df.shape, dtype=np.float64) return arr.tocsr() 

    Hier ist eine Lösung, die die Sparse Matrix Spalte nach Spalte füllt (vorausgesetzt, Sie können mindestens eine Spalte in den Speicher passen).

     import pandas as pd import numpy as np from scipy.sparse import lil_matrix def sparse_df_to_array(df): """ Convert sparse dataframe to sparse array csr_matrix used by scikit learn. """ arr = lil_matrix(df.shape, dtype=np.float32) for i, col in enumerate(df.columns): ix = df[col] != 0 arr[np.where(ix), i] = df.ix[ix, col] return arr.tocsr() 

    Sie sollten in der Lage sein, die experimentelle .to_coo() Methode in Pandas [1] wie folgt zu verwenden:

     df, idx_rows, idx_cols = df.stack().to_sparse().to_coo() df = df.tocsr() 

    Diese Methode, anstatt ein DataFrame (Zeilen / Spalten) zu nehmen, braucht es eine Series mit Zeilen und Spalten in einem MultiIndex (das ist, warum Sie die .stack() Methode benötigen). Diese Series mit dem MultiIndex muss ein SparseSeries , und selbst wenn deine Eingabe ein SparseDataFrame , gibt der .stack() eine reguläre Series . Also musst du die .to_sparse() Methode verwenden, bevor du .to_sparse() .to_coo() .

    Die Series kehrte von .stack() , auch wenn es nicht ein SparseSeries nur die Elemente gibt, die nicht null sind, also sollte es nicht mehr Speicher als die spärliche Version nehmen (zumindest mit np.nan wenn der Typ np.float ).

    1. http://pandas.pydata.org/pandas-docs/stable/sparse.html#interaction-with-scipy-sparse
    Python ist die beste Programmiersprache der Welt.