it-swarm.com.de

So speichern Sie ein Datenframe mit Pandas

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

205
jeffstern

Am einfachsten ist es, pickle es mit to_pickle zu verwenden:

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 save und load die einzige Möglichkeit, dies zu tun (sie sind jetzt zugunsten von to_pickle und 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

Weitergehende Strategien werden im Kochbuch diskutiert.


Seit 0.13 gibt es auch msgpack , was für Interoperabilität besser geeignet sein kann, als schnellere Alternative zu JSON oder wenn Sie Python-Objekt/Text-schwere Daten haben (siehe diese Frage ).

336
Andy Hayden

Obwohl es bereits einige Antworten gibt, habe ich einen Vergleich mit Nizza gefunden, bei dem versucht wurde, Pandas DataFrames auf verschiedene Weise zu serialisieren: Effizientes Speichern von Pandas DataFrames

Sie vergleichen:

  • pickle: Originales Datenformat ASCII
  • 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 sagt:

Sie sollten nicht darauf vertrauen, dass das Folgende zu Ihren Daten passt. Sie sollten sich Ihre eigenen Daten ansehen und selbst Benchmarks durchführen

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

 time comparison results

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

Edit: Die höheren Zeiten für Pickle als csv können durch das verwendete Datenformat erklärt werden. Standardmäßig verwendet pickle eine druckbare ASCII -Darstellung, die größere Datensätze erzeugt. Wie aus der Grafik zu ersehen ist, hat Pickle mit dem neueren binären Datenformat (Version 2, pickle-p2) jedoch wesentlich geringere Ladezeiten.

Einige andere Referenzen:

68
agold

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

  1. sie können mit pandas.read_csv(..., nrows=1000) nur einen Teil der CSV-Datei 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 im Arbeitsspeicher behalten, wenn Sie Ihr Skript bearbeiten und neu laden.

  3. konvertieren Sie die CSV-Datei in eine HDF5-Tabelle

  4. updated verwende 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() für numerische Daten und viel schneller für Zeichenfolgendaten).

Vielleicht interessieren Sie sich auch für diese Antwort bei stackoverflow.

28
Noah

Pickle 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
17

Pandas DataFrames haben die to_pickle-Funktion, 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
#    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

Sie können eine Federformatdatei verwenden. Es ist extrem schnell.

df.to_feather('filename.ft')
3
Huanyu Liao

Wie bereits erwähnt gibt es verschiedene Optionen und Dateiformate ( HDF5 , JSON , CSV , parkett , SQL ) zum Speichern eines Datenrahmen. pickle ist jedoch kein erstklassiger Bürger (abhängig von Ihrer Konfiguration), da:

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

Warnung Das Modul pickle ist nicht sicher gegen fehlerhafte oder in böswilliger Absicht erstellte Daten. Entpicken Sie niemals Daten, die von einer nicht vertrauenswürdigen oder nicht authentifizierten Quelle stammen.

2) pickle ist langsam. Finden Sie hier und hier Benchmarks.

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

3
Michael Dorner

Unzureichende Dateiformate sind für numerische Daten ziemlich schnell

Ich ziehe es vor, numpy-Dateien zu verwenden, da sie schnell und einfach zu bearbeiten sind .. Hier ist ein einfacher Maßstab zum Speichern und Laden eines Datenrahmens mit einer 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 ipcode-Funktion %%timeit magic

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

CONS

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

2
mark jay

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

Die Pickle-Protokollformate:

Protokollversion 0 ist das ursprüngliche, von Menschen 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 ermöglicht ein effizienteres Beizen von Klassen neuen Stils. Weitere Informationen zu Verbesserungen durch Protokoll 2 finden Sie in PEP 307.

Protokollversion 3 wurde in Python 3.0 hinzugefügt. Es unterstützt Bytes-Objekte explizit 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 mehrerer Arten von Objekten und einige Datenformatoptimierungen. Weitere Informationen zu Verbesserungen durch Protokoll 4 finden Sie in PEP 3154.

0
Gilco
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 zwei Zeilen öffnen die gespeicherte Pickle-Datei

0
Anirban Manna