Introduction
En Python, un fichier pickle (.pkl ou .pickle) est un moyen de sérialiser et sauvegarder des objets Python sur disque — c'est-à-dire convertir des objets Python (listes, dictionnaires, modèles, DataFrames, etc.) en un flux de bytes, qui pourra ensuite être désérialisé (rechargé en mémoire exactement comme avant).
Ce que signifie “Pickling”
- Pickling → convertir un objet Python en flux binaire (pour le sauvegarder dans un fichier ou l’envoyer par réseau).
- Unpickling → convertir le flux binaire pour retrouver l’objet Python original.
Pourquoi c’est utile ?
Vous pouvez utiliser pickle pour :
- Sauvegarder des modèles de machine learning (scikit-learn, XGBoost, etc.)
- Stocker des données prétraitées ou des résultats intermédiaires
- Mettre en cache des objets complexes (dictionnaires, listes, DataFrames, etc.)
Exemple d’utilisation
Sauvegarder (Pickler) un objet
1 2 3 4 5 6 7 | import pickle data = {'name': 'Benjamin', 'scores': [85, 92, 78]} # Save to file with open('data.pkl', 'wb') as f: pickle.dump(data, f) |
'wb' signifie “write binary” (écriture binaire).
Charger (Unpickler) l’objet
1 2 3 4 5 6 7 8 | import pickle # Load from file with open('data.pkl', 'rb') as f: loaded_data = pickle.load(f) print(loaded_data) # {'name': 'Benjamin', 'scores': [85, 92, 78]} |
'rb' signifie “read binary” (lecture binaire).
Notes importantes
-
Avertissement de sécurité :
Ne jamais unpickler des données provenant d’une source non fiable.
pickle.load()peut exécuter du code Python arbitraire. -
Compatibilité :
Les fichiers pickle dépendent de la version Python.
Un fichier créé sous Python 3.11 peut ne pas fonctionner parfaitement sous Python 3.9. -
Alternatives :
-
Pour un stockage sûr et interopérable →
json,csv,parquet - Pour les modèles ML →
joblib,torch.save,tf.keras.models.save
Exemples de Base avec Pickle
Exemple 1 : Pickler un DataFrame pandas
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | import pandas as pd import pickle df = pd.DataFrame({ 'city': ['New York', 'Paris', 'Tokyo'], 'temperature': [22, 19, 25] }) # Save with open('weather.pkl', 'wb') as f: pickle.dump(df, f) # Load with open('weather.pkl', 'rb') as f: df_loaded = pickle.load(f) print(df_loaded) |
Sortie :
1 2 3 4 | city temperature 0 New York 22 1 Paris 19 2 Tokyo 25 |
Méthode pratique via pandas :
1 2 | df.to_pickle('weather.pkl') df_loaded = pd.read_pickle('weather.pkl') |
Exemple 2 : Pickler un modèle entraîné de machine learning
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | from sklearn.ensemble import RandomForestClassifier from sklearn.datasets import load_iris import pickle X, y = load_iris(return_X_y=True) model = RandomForestClassifier() model.fit(X, y) with open('rf_model.pkl', 'wb') as f: pickle.dump(model, f) with open('rf_model.pkl', 'rb') as f: loaded_model = pickle.load(f) print(loaded_model.predict([[5.1, 3.5, 1.4, 0.2]])) |
Sortie :
1 | [0] |
Astuce : préférer joblib pour les gros modèles
1 2 3 4 | import joblib joblib.dump(model, 'rf_model.joblib') model_loaded = joblib.load('rf_model.joblib') |
Pickler plusieurs objets dans un seul fichier
La méthode la plus propre :
mettre tout dans un dictionnaire, puis pickler le dictionnaire.
Ainsi, un seul fichier .pkl contient :
- modèle
- scaler
- noms des features
- métadonnées
- hyperparamètres, etc.
Exemple : Pickler plusieurs objets
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | import pickle from sklearn.preprocessing import StandardScaler from sklearn.ensemble import RandomForestRegressor import numpy as np X = np.random.rand(100, 3) y = np.random.rand(100) scaler = StandardScaler() X_scaled = scaler.fit_transform(X) model = RandomForestRegressor() model.fit(X_scaled, y) feature_names = ['feat1', 'feat2', 'feat3'] metadata = {'version': '1.0', 'created_by': 'Benjamin'} bundle = { 'model': model, 'scaler': scaler, 'features': feature_names, 'metadata': metadata } with open('model_bundle.pkl', 'wb') as f: pickle.dump(bundle, f) |
Chargement :
1 2 3 4 5 6 7 8 9 10 | with open('model_bundle.pkl', 'rb') as f: bundle = pickle.load(f) model = bundle['model'] scaler = bundle['scaler'] features = bundle['features'] metadata = bundle['metadata'] print(metadata) print(features) |
Utilisation :
1 2 3 4 | new_data = np.array([[0.2, 0.5, 0.9]]) new_data_scaled = scaler.transform(new_data) pred = model.predict(new_data_scaled) print(pred) |
Bonne pratique : toujours packer tout dans un dictionnaire.
Checkpointing de longues boucles
Quand une boucle dure longtemps, on veut pouvoir reprendre après un crash.
Pickle est parfait pour cela.
Exemple 1 — Sauvegarder tous les N itérations
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | import pickle import os progress_file = "progress.pkl" if os.path.exists(progress_file): with open(progress_file, "rb") as f: data = pickle.load(f) start_index = data["index"] results = data["results"] print(f"Resuming from iteration {start_index}...") else: start_index = 0 results = [] for i in range(start_index, 1000000): try: result = i ** 2 results.append(result) if i % 1000 == 0: with open(progress_file, "wb") as f: pickle.dump({"index": i + 1, "results": results}, f) print(f"Checkpoint saved at iteration {i}") except Exception as e: print("Error occurred:", e) break |
Exemple 2 — Sauvegarder chaque itération
1 | pickle.dump({"index": i + 1, "results": results}, open("progress.pkl", "wb")) |
Exemple 3 — Sauver uniquement l’état minimal
1 2 | state = {"i": i, "partial_result": partial_object} pickle.dump(state, open("checkpoint.pkl", "wb")) |
Exemple 4 — Sauvegarder uniquement en cas d’erreur
1 2 3 4 5 6 7 | try: for i in range(start_index, N): do_work() except Exception as e: print("Error detected, saving checkpoint...") pickle.dump({"i": i, "results": results}, open("progress.pkl", "wb")) raise e |
Recharger
1 2 3 4 5 | with open("progress.pkl", "rb") as f: data = pickle.load(f) start_i = data["i"] results = data["results"] |
Ce qu’on peut sauvegarder
- index courant
- liste de résultats
- objets temporaires
- états intermédiaires de modèles
- DataFrames partiels
- métadonnées
Avertissements
Ne pas pickler d'immenses tableaux NumPy en boucle
préférez .npy, .parquet
Ne pas unpickler des fichiers suspects
risque d’exécution de code malveillant
Système de checkpointing réutilisable
1. Fonctions utilitaires
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | import pickle import os def save_checkpoint(path, data): with open(path, "wb") as f: pickle.dump(data, f) def load_checkpoint(path, default=None): if os.path.exists(path): with open(path, "rb") as f: return pickle.load(f) return default def delete_checkpoint(path): if os.path.exists(path): os.remove(path) |
2. Exemple d’utilisation
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | from checkpoint import save_checkpoint, load_checkpoint checkpoint_path = "progress.pkl" state = load_checkpoint(checkpoint_path, default={"i": 0, "results": []}) start_i = state["i"] results = state["results"] print(f"Resuming at iteration {start_i} with {len(results)} saved results.") N = 1_000_000 for i in range(start_i, N): try: value = i ** 2 results.append(value) if i % 1000 == 0: save_checkpoint(checkpoint_path, {"i": i + 1, "results": results}) print(f"Checkpoint saved at iteration {i}") except Exception as e: print("ERROR OCCURRED — saving checkpoint before quitting...") save_checkpoint(checkpoint_path, {"i": i, "results": results}) raise e |
Après un crash : ré-exécuter → reprise automatique.
Références
| Liens | Site |
|---|---|
| pickle — Python object serialization | Documentation Python |
| Serialization — Python Guide | Persistence et pickle |
| DigitalOcean — Python Pickle Example | Tutoriel pratique |
