Im Moment importiere ich jedes Mal, wenn ich das Skript ausführe, ein ziemlich großes CSV als Datenrahmen. Gibt es eine gute Lösung, um diesen Datenrahmen zwischen den Läufen ständig verfügbar zu halten, damit ich nicht die ganze Zeit auf die Ausführung des Skripts warten muss?

299
jeffstern 14 Juni 2013 im 03:05

10 Antworten

Beste Antwort

Am einfachsten ist es, mit to_pickle:

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

Dann können Sie es wieder laden mit:

df = pd.read_pickle(file_name)

Hinweis: Vor 0.11.1 waren save und load die einzige Möglichkeit, dies zu tun (sie sind jetzt zugunsten von to_pickle bzw. read_pickle veraltet).


Eine weitere beliebte Option ist die Verwendung von HDF5 (pytables), das sehr schnelle Zugriffszeiten für große Datenmengen:

store = HDFStore('store.h5')

store['df'] = df  # save it
store['df']  # load it

Weiterführende Strategien werden im Kochbuch.


Seit 0.13 gibt es auch msgpack, für das es möglicherweise besser ist Interoperabilität als schnellere Alternative zu JSON oder wenn Sie über Python-Objekt- / Text-schwere Daten verfügen (siehe diese Frage).

454
Community 23 Mai 2017 im 11:54

Wenn ich das richtig verstehe, verwenden Sie bereits pandas.read_csv(), möchten aber den Entwicklungsprozess beschleunigen, damit 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 Ihres Skripts im Speicher behalten.

  3. Konvertieren Sie die CSV in eine HDF5-Tabelle

  4. aktualisiert Verwenden Sie DataFrame.to_feather() und pd.read_feather(), um Daten im R-kompatiblen zu speichern. > Feder Binärformat, das superschnell ist (in meinen Händen etwas schneller als pandas.to_pickle() bei numerischen Daten und viel schneller bei Zeichenfolgendaten).

Möglicherweise interessiert Sie auch diese Antwort für stackoverflow.

33
Vlad 30 Juni 2017 im 17:43

Gurke 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
19
Anbarasu Ramachandran 1 Dez. 2015 im 10:44

https://docs.python.org/3/library/pickle.html

Die Pickle-Protokollformate:

Protokollversion 0 ist das ursprüngliche "lesbare" Protokoll und abwärtskompatibel mit früheren Versionen von Python.

Protokollversion 1 ist ein altes Binärformat, das auch mit früheren Versionen von Python kompatibel ist.

Protokoll Version 2 wurde in Python 2.3 eingeführt. Es bietet ein viel effizienteres Beizen von Klassen neuen Stils. Informationen zu Verbesserungen durch Protokoll 2 finden Sie in PEP 307.

Protokollversion 3 wurde in Python 3.0 hinzugefügt. Es unterstützt explizit Byte-Objekte und kann von Python 2.x nicht entfernt werden. Dies ist das Standardprotokoll und das empfohlene Protokoll, wenn Kompatibilität mit anderen Python 3-Versionen erforderlich ist.

Protokollversion 4 wurde in Python 3.4 hinzugefügt. Es bietet Unterstützung für sehr große Objekte, das Beizen weiterer Objekttypen und einige Optimierungen des Datenformats. Informationen zu Verbesserungen durch Protokoll 4 finden Sie in PEP 3154.

0
Gilco 12 Apr. 2019 im 06:18

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

df.to_feather('filename.ft')
4
Huanyu Liao 17 Okt. 2017 im 06:28
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 Pickle-Datei

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

Diese beiden Zeilen öffnen die gespeicherte Pickle-Datei

-1
Anirban Manna 16 Jän. 2018 im 17:20

Obwohl es bereits einige Antworten gibt, habe ich einen schönen Vergleich gefunden, bei dem versucht wurde, Pandas DataFrames auf verschiedene Arten zu serialisieren: Pandas DataFrames effizient speichern.

Sie vergleichen:

  • pickle: 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 mit 1.000.000 Zeilen, wobei die beiden Spalten separat getestet werden: eine mit Textdaten, die andere mit Zahlen. Ihr Haftungsausschluss lautet:

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

Der Quellcode für den Test, auf den sie verweisen, ist online verfügbar. Da dieser Code nicht direkt funktioniert hat, habe ich einige geringfügige Änderungen vorgenommen, die Sie hier erhalten können: serialize.py Ich habe folgende Ergebnisse erhalten:

time comparison results

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

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

Einige andere Referenzen:

93
MadMike 12 Juni 2019 im 14:10

Numpy Dateiformate sind für numerische Daten ziemlich schnell

Ich bevorzuge die Verwendung von Numpy-Dateien, da diese schnell und einfach zu bearbeiten sind. Hier ist ein einfacher Benchmark zum Speichern und Laden eines Datenrahmens mit 1 Spalte mit 1 Million Punkten.

import numpy as np
import pandas as pd

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

Verwenden der magischen Funktion %%timeit von ipython

%%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 wieder 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!

Nachteile

Es gibt ein Problem, wenn Sie die Numpy-Datei mit Python 2 speichern und dann versuchen, sie mit Python 3 zu öffnen (oder umgekehrt).

1
mark jay 13 Okt. 2017 im 18:31

Wie bereits erwähnt, gibt es verschiedene Optionen und Dateiformate (HDF5, JSON, CSV, Parkett, SQL) zum Speichern eines Datenrahmens. pickle ist jedoch kein erstklassiger Bürger (abhängig von Ihrem Setup), weil:

  1. pickle ist ein potenzielles Sicherheitsrisiko. Bilden Sie die Python-Dokumentation für Pickle:

Warnung Das Modul pickle ist nicht gegen fehlerhafte oder fehlerhafte Vorgänge geschützt böswillig konstruierte Daten. Entfernen Sie niemals die von einem empfangenen Daten nicht vertrauenswürdige oder nicht authentifizierte Quelle.

  1. pickle ist langsam. Finden Sie hier und hier Benchmarks.

Abhängig von Ihrem Setup / Ihrer Verwendung gelten beide Einschränkungen nicht, aber ich würde pickle nicht als Standardpersistenz für Pandas-Datenrahmen empfehlen.

4
Fozoro 9 Aug. 2019 im 10:17

Pandas DataFrames verfügen über die Funktion to_pickle, die zum Speichern eines DataFrames hilfreich ist:

import pandas as pd

a = pd.DataFrame({'A':[0,1,0,1,0],'B':[True, True, False, False, False]})
print a
#    A      B
# 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
#    A      B
# 0  0   True
# 1  1   True
# 2  0  False
# 3  1  False
# 4  0  False
4
mgoldwasser 12 Nov. 2015 im 21:46