Comment stocker une dataframe en utilisant Pandas
en ce moment, j'importe un assez grand CSV
comme dataframe à chaque fois que j'exécute le script. Y a-t-il une bonne solution pour garder cette dataframe constamment disponible entre les différentes versions, pour que je n'aie pas à passer tout ce temps à attendre que le script tourne?
8 réponses
la manière la plus simple est de pickle IT en utilisant to_pickle
:
df.to_pickle(file_name) # where to save it, usually as a .pkl
puis vous pouvez le recharger en utilisant:
df = pd.read_pickle(file_name)
Note: avant 0.11.1 save
et load
étaient la seule façon de le faire (ils sont maintenant dépréciés en faveur de to_pickle
et read_pickle
respectivement).
un Autre le choix populaire est d'utiliser HDF5 ( pytables ) qui offre très rapide temps d'accès pour les grands ensembles de données:
store = HDFStore('store.h5')
store['df'] = df # save it
store['df'] # load it
des stratégies plus avancées sont discutées dans le cookbook .
depuis 0.13 il y a aussi msgpack ce qui pourrait être mieux pour l'interopérabilité, comme alternative plus rapide à JSON, ou si vous avez des données Python object/text-heavy (voir cette question ).
bien qu'il y ait déjà quelques réponses, j'ai trouvé une belle comparaison dans laquelle ils ont essayé plusieurs façons de sérialiser Pandas DataFrames: efficacement stocker Pandas DataFrames .
ils comparent:
- pickle: origine des données ASCII format
- cPickle, une bibliothèque C
- pickle-p2: utilise le nouveau format binaire
- JSON: standardlib json bibliothèque
- json-no-index: comme json, mais sans indice
- msgpack: binaire JSON alternative
- CSV
- hdfstore: HDF5 storage format
dans leur expérience ils sérialisent un datagramme de 1.000.000 lignes avec les deux colonnes testées séparément: l'une avec des données de texte, l'autre avec des nombres. Leur disclaimer dit:
vous devriez ne croyez pas que ce qui suit généralise à vos données. Vous devriez regarder vos propres données et exécuter des benchmarks vous-même
le code source du test auquel ils se réfèrent est disponible en ligne . Comme CE code n'a pas fonctionné directement j'ai fait quelques changements mineurs, que vous pouvez obtenir ici: serialize.py J'ai eu les résultats suivants:
ils mentionnent également qu'avec la conversion des données de texte en catégorique données la sérialisation est beaucoup plus rapide. Dans leur test environ 10 fois plus rapide (Voir aussi le code de test).
Edit : les temps de pickle plus élevés que csv peuvent être expliqués par le format de données utilisé. Par défaut pickle
utilise une représentation ASCII imprimable, qui génère des ensembles de données plus grands. Comme peut être vu du graphique cependant, pickle en utilisant le nouveau format de données binaires (version 2, pickle-p2
) a beaucoup plus de temps de charge.
autres références:
- dans la question la bibliothèque Python la plus rapide pour lire un fichier CSV il y a une réponse très détaillée qui compare différentes bibliothèques pour lire des fichiers csv avec un benchmark. Le résultat est que pour la lecture des fichiers csv
numpy.fromfile
est le plus rapide. - l'Autre sérialisation test montre msgpack-python , ujson , et cPickle pour être le plus rapide dans la sérialisation.
si je comprends bien, vous utilisez déjà pandas.read_csv()
mais vous souhaitez accélérer le processus de développement afin que vous n'ayez pas à charger le fichier à chaque fois que vous éditez votre script, est-ce vrai? J'ai quelques recommandations:
-
vous pouvez charger seulement une partie du fichier CSV en utilisant
pandas.read_csv(..., nrows=1000)
pour ne charger que la partie supérieure de la table, pendant que vous faites le développement -
utilisation ipython pour une session interactive, de sorte que vous gardez les pandas tableau dans la mémoire comme vous de modifier et de recharger votre script.
-
convertissez le csv en HDF5 table
-
mise à jour utiliser
DataFrame.to_feather()
etpd.read_feather()
pour stocker des données dans la R-compatible plume format binaire qui est super rapide (dans mon mains, légèrement plus rapide quepandas.to_pickle()
sur les données numériques et beaucoup plus rapide sur les données string).
Vous pourriez également être intéressé par cette réponse sur stackoverflow.
Pickle fonctionne bien!
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
les bases de données Pandas ont la fonction to_pickle
qui est utile pour sauvegarder une base de données:
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
vous pouvez utiliser un fichier au format plume. Il est extrêmement rapide.
df.to_feather('filename.ft')
les formats de fichier Numpy sont assez rapides pour les données numériques
je préfère utiliser les fichiers numpy car ils sont rapides et faciles à utiliser. Voici un benchmark simple pour sauvegarder et charger une dataframe avec 1 colonne de 1 million de points.
import numpy as np
import pandas as pd
num_dict = {'voltage': np.random.rand(1000000)}
num_df = pd.DataFrame(num_dict)
à l'aide de ipython %%timeit
la magie de la fonction
%%timeit
with open('num.npy', 'wb') as np_file:
np.save(np_file, num_df)
la sortie est
100 loops, best of 3: 5.97 ms per loop
pour recharger les données dans un cadre de données
%%timeit
with open('num.npy', 'rb') as np_file:
data = np.load(np_file)
data_df = pd.DataFrame(data)
la sortie est
100 loops, best of 3: 5.12 ms per loop
PAS MAL!
CONS
il y a un problème si vous enregistrez le fichier numpy en utilisant python 2, puis essayez l'ouverture en utilisant python 3 (ou vice versa).
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()
le code ci-dessus enregistrera le fichier pickle
pickle_in = open("dict.pickle","rb")
example_dict = pickle.load(pickle_in)
ces deux lignes ouvriront le fichier de pickle enregistré