Wie man einen Datenrahmen mit Pandas speichert

Im Moment importiere ich jedes Mal, wenn ich das Skript ausführe, eine ziemlich große CSV als Datenrahmen. Gibt es eine gute Lösung, um den Datenrahmen zwischen den Läufen konstant verfügbar zu halten, sodass ich nicht die ganze Zeit darauf warten muss, dass das Skript ausgeführt wird?

Der einfachste Weg ist, ihn mit to_pickle :

 df.to_pickle(file_name) # where to save it, usually as a .pkl 

Dann können Sie es zurückladen mit:

 df = pd.read_pickle(file_name) 

Hinweis: Vor 0.11.1 waren das save und load der einzige Weg, dies zu tun (sie sind jetzt zugunsten von to_pickle bzw. read_pickle veraltet).


Eine andere beliebte Wahl ist die Verwendung von HDF5 ( Pytables ), die sehr schnelle Zugriffszeiten für große Datensätze bietet:

 store = HDFStore('store.h5') store['df'] = df # save it store['df'] # load it 

Fortgeschrittenere Strategien werden im Kochbuch diskutiert.


Seit 0.13 gibt es auch msgpack, was möglicherweise besser für die Interoperabilität ist, als eine schnellere Alternative zu JSON oder wenn Sie Python-Objekt / textlastige Daten haben (siehe diese Frage ).

Obwohl es bereits einige Antworten gibt, habe ich einen schönen Vergleich gefunden, in dem sie verschiedene Möglichkeiten zum Serialisieren von Pandas DataFrames ausprobiert haben: Speichern Sie Pandas DataFrames effizient .

Sie vergleichen:

  • Beize: Original ASCII-Datenformat
  • cPickle, eine C-Bibliothek
  • pickle-p2: verwendet das neuere Binärformat
  • json: standardlib json-Bibliothek
  • json-no-index: wie json, aber ohne index
  • msgpack: binäre JSON-Alternative
  • CSV
  • hdfstore: HDF5 Speicherformat

In ihrem Experiment serialisieren sie einen DataFrame von 1.000.000 Zeilen mit den beiden separat getesteten Spalten: eine mit Textdaten, die andere mit Zahlen. Ihr Haftungsausschluss sagt:

Sie sollten nicht darauf vertrauen, dass das, was folgt, auf Ihre Daten verallgemeinert wird. Sie sollten sich Ihre eigenen Daten ansehen und Benchmarks selbst ausführen

Der Quellcode für den Test, auf den sie sich beziehen, ist online verfügbar . Da dieser Code nicht direkt funktionierte, habe ich einige kleinere Änderungen vorgenommen, die Sie hier bekommen: serialize.py Ich habe folgende Ergebnisse erhalten:

Zeitvergleichsergebnisse

Sie erwähnen auch, dass mit der Umwandlung von Textdaten in kategorische Daten die Serialisierung viel schneller ist. In ihrem Test etwa 10 mal so schnell (siehe auch Testcode).

Bearbeiten : Die höheren Zeiten für Gurke als CSV können durch das verwendete Datenformat erklärt werden. Standardmäßig verwendet pickle eine druckbare ASCII-Darstellung, die größere Datensätze generiert. Wie aus dem Graphen ersichtlich ist, hat Pickle mit dem neueren Binärdatenformat (Version 2, pickle-p2 ) wesentlich kürzere Ladezeiten.

Einige andere Referenzen:

  • In der Frage Schnellste Python-Bibliothek zum Lesen einer CSV-Datei gibt es eine sehr detaillierte Antwort, die verschiedene Bibliotheken vergleicht , um CSV- Dateien mit einem Benchmark zu lesen. Das Ergebnis ist, dass zum Lesen von numpy.fromfile Dateien numpy.fromfile am schnellsten ist.
  • Ein weiterer Serialisierungstest zeigt msgpack-python , ujson und cPickle als die schnellste Serialisierung an.

Wenn ich richtig verstanden habe, benutzen Sie bereits pandas.read_csv() , möchten aber den Entwicklungsprozess beschleunigen, so dass Sie die Datei nicht jedes Mal laden müssen, wenn Sie Ihr Skript bearbeiten, ist das richtig? Ich habe ein paar Empfehlungen:

  1. Sie können nur einen Teil der CSV-Datei mit pandas.read_csv(..., nrows=1000) laden, um nur das oberste Bit der Tabelle zu laden, während Sie die Entwicklung durchführen

  2. Verwenden Sie ipython für eine interaktive Sitzung, sodass Sie die pandas-Tabelle beim Bearbeiten und erneuten Laden des Skripts im Speicher behalten.

  3. Konvertieren Sie den CSV in eine HDF5-Tabelle

  4. aktualisiert DataFrame.to_feather() und pd.read_feather() zum Speichern von Daten im R-kompatiblen Feder- Binärformat, das superschnell ist (in meinen Händen, etwas schneller als pandas.to_pickle() bei numerischen Daten und viel schneller bei Zeichenkettendaten) ).

Diese Antwort könnte Sie auch auf stackoverflow interessieren.

Essiggurke funktioniert gut!

 import pandas as pd df.to_pickle('123.pkl') #to save the dataframe, df to 123.pkl df1 = pd.read_pickle('123.pkl') #to load 123.pkl back to the dataframe df 

Pandas DataFrames haben die function to_pickle , die zum Speichern eines Dataframes nützlich ist:

 import pandas as pd a = pd.DataFrame({'A':[0,1,0,1,0],'B':[True, True, False, False, False]}) print a # AB # 0 0 True # 1 1 True # 2 0 False # 3 1 False # 4 0 False a.to_pickle('my_file.pkl') b = pd.read_pickle('my_file.pkl') print b # AB # 0 0 True # 1 1 True # 2 0 False # 3 1 False # 4 0 False 

Sie können die Datei im Federformat verwenden. Es ist extrem schnell.

 df.to_feather('filename.ft') 

Numpy Dateiformate sind ziemlich schnell für numerische Daten

Ich bevorzuge es, numpy Dateien zu verwenden, da sie schnell und einfach zu arbeiten sind. Hier ist ein einfacher Benchmark zum Speichern und Laden eines Datenrahmens mit 1 Spalte von 1 Millionen Punkten.

 import numpy as np import pandas as pd num_dict = {'voltage': np.random.rand(1000000)} num_df = pd.DataFrame(num_dict) 

mit ipythons %%timeit magic-function

 %%timeit with open('num.npy', 'wb') as np_file: np.save(np_file, num_df) 

die Ausgabe ist

 100 loops, best of 3: 5.97 ms per loop 

um die Daten zurück in einen Datenrahmen zu laden

 %%timeit with open('num.npy', 'rb') as np_file: data = np.load(np_file) data_df = pd.DataFrame(data) 

die Ausgabe ist

 100 loops, best of 3: 5.12 ms per loop 

NICHT SCHLECHT!

CONS

Es gibt ein Problem, wenn du die numpy Datei mit Python 2 speicherst und dann öffnest mit Python 3 (oder umgekehrt).

 import pickle example_dict = {1:"6",2:"2",3:"g"} pickle_out = open("dict.pickle","wb") pickle.dump(example_dict, pickle_out) pickle_out.close() 

Der obige Code speichert die Beizdatei

 pickle_in = open("dict.pickle","rb") example_dict = pickle.load(pickle_in) 

Diese zwei Zeilen öffnen die gespeicherte Beizdatei