À l'heure actuelle, j'importe une CSV
assez grande en tant que cadre de données chaque fois que j'exécute le script. Existe-t-il une bonne solution pour garder ce cadre de données constamment disponible entre les exécutions afin que je n'ai pas à passer tout ce temps à attendre l'exécution du script?
Le moyen le plus simple est de pickle it en utilisant to_pickle
:
df.to_pickle(file_name) # where to save it, usually as a .pkl
Ensuite, vous pouvez le recharger en utilisant:
df = pd.read_pickle(file_name)
Remarque: avant la version 0.11.1, save
et load
étaient le seul moyen de procéder (elles sont maintenant déconseillées en faveur de to_pickle
et read_pickle
).
Un autre choix courant consiste à utiliser HDF5 ( pytables ) qui offre très rapidement 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 livre de recettes .
Depuis 0.13, il y a aussi msgpack qui peut être meilleur pour l'interopérabilité, comme alternative plus rapide au JSON ou si vous avez des données python-objet/text-heavy (voir cette question ).
Bien qu'il y ait déjà quelques réponses, j'ai trouvé une comparaison intéressante dans laquelle ils ont essayé plusieurs façons de sérialiser Pandas DataFrames: Stocker efficacement les Pandas DataFrames .
Ils comparent:
Dans leur expérience, ils sérialisent un DataFrame de 1 000 000 lignes avec les deux colonnes testées séparément: une avec des données de texte, l'autre avec des nombres. Leur disclaimer dit:
Vous ne devez pas croire que ce qui suit se généralise à vos données. Vous devriez examiner vos propres données et exécuter vous-même des tests de performance.
Le code source du test auquel ils font référence est disponible en ligne . Comme ce code ne fonctionnait pas directement, j'ai apporté quelques modifications mineures, que vous pouvez obtenir ici: serialize.py J'ai eu les résultats suivants:
Ils mentionnent également qu'avec la conversion de données texte en données catégoriques , la sérialisation est beaucoup plus rapide. Dans leur test environ 10 fois plus rapide (voir aussi le code de test).
Edit: le format de données utilisé peut expliquer les temps de pickle supérieurs à ceux de csv. Par défaut, pickle
utilise une représentation imprimable ASCII, qui génère des jeux de données plus volumineux. Comme on peut le voir sur le graphique, le pickle utilisant le nouveau format de données binaires (version 2, pickle-p2
) a des temps de chargement beaucoup plus courts.
Quelques autres références:
numpy.fromfile
est le plus rapide.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 modifiez votre script, est-ce exact? J'ai quelques recommandations:
vous pouvez charger seulement une partie du fichier CSV en utilisant pandas.read_csv(..., nrows=1000)
pour ne charger que le bit le plus haut de la table, pendant que vous faites le développement
utilisez ipython pour une session interactive, telle que vous gardiez la table pandas en mémoire lorsque vous modifiez et rechargez votre script.
convertir le csv en un table HDF5
updated utilise DataFrame.to_feather()
et pd.read_feather()
pour stocker des données dans un format binaire feather compatible avec R très rapide (entre mes mains, légèrement plus rapide que pandas.to_pickle()
pour les données numériques et beaucoup plus rapide pour les données de chaîne).
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 Pandas DataFrames ont la fonction to_pickle
qui est utile pour enregistrer un DataFrame:
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 de format de plume. C'est extrêmement rapide.
df.to_feather('filename.ft')
Comme déjà mentionné, il existe différentes options et formats de fichier ( HDF5 , JSON , CSV , parquet , SQL ) pour stocker un trame de données. Cependant, pickle
n'est pas un citoyen de première classe (selon votre configuration), car:
1) pickle
est un risque potentiel pour la sécurité. Former la documentation Python pour pickle :
Avertissement Le module
pickle
n'est pas sécurisé contre les données erronées ou mal construites. Ne supprimez jamais les données reçues d'une source non fiable ou non authentifiée.
2) pickle
est lent. Trouvez ici et ici points de repère.
En fonction de votre configuration/utilisation, les deux limitations ne s'appliquent pas, mais je ne recommanderais pas pickle
comme persistance par défaut pour les trames de données pandas.
Je préfère utiliser les fichiers numpy car ils sont rapides et faciles à utiliser ..__ Voici un repère simple pour enregistrer et charger une trame de données 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)
en utilisant la fonction magique %%timeit
de ipython
%%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
charger 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!
Il y a un problème si vous enregistrez le fichier numpy à l'aide de python 2 puis essayez d'ouvrir à l'aide de python 3 (ou inversement).
https://docs.python.org/3/library/pickle.html
Les formats de protocole de pickle:
La version 0 du protocole est le protocole original "lisible par l'homme" et est rétrocompatible avec les versions antérieures de Python.
La version 1 du protocole est un ancien format binaire compatible avec les versions antérieures de Python.
La version 2 du protocole a été introduite dans Python 2.3. Il permet un décapage beaucoup plus efficace des classes d'un nouveau style. Reportez-vous au PEP 307 pour plus d'informations sur les améliorations apportées par le protocole 2.
La version 3 du protocole a été ajoutée dans Python 3.0. Il supporte explicitement les objets bytes et ne peut pas être annulé par Python 2.x. Il s'agit du protocole par défaut et du protocole recommandé lorsque la compatibilité avec d'autres versions de Python 3 est requise.
La version 4 du protocole a été ajoutée dans Python 3.4. Il ajoute la prise en charge des objets très volumineux, la sélection de plusieurs types d'objets et certaines optimisations de format de données. Reportez-vous au PEP 3154 pour plus d’informations sur les améliorations apportées par le protocole 4.
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 sauvera le fichier pickle
pickle_in = open("dict.pickle","rb")
example_dict = pickle.load(pickle_in)
Ces deux lignes ouvriront le fichier pickle enregistré