Menu
CoddyTech

Aide-mémoire pandas

Dernière mise à jour

Créer un DataFrame

De petits DataFrames construits à la main, pour les exemples, les tests et les tables de correspondance.

TâcheCode
Importer pandas et NumPyimport pandas as pd import numpy as np
À partir d'un dict de colonnesdf = pd.DataFrame({"name": ["Ada", "Ben"], "age": [36, 28]})
À partir d'une liste de lignespd.DataFrame([{"name": "Ada", "age": 36}, {"name": "Ben", "age": 28}])
À partir d'un tableau NumPypd.DataFrame(np.arange(6).reshape(3, 2), columns=["x", "y"])
Une Series avec des étiquettess = pd.Series([3, 5, 2], index=["a", "b", "c"])
Une plage de datespd.date_range("2026-01-01", periods=7, freq="D")

Lire et écrire des fichiers

Un seul appel charge un fichier dans un DataFrame, et un seul appel le réécrit.

TâcheCode
Lire un fichier CSVdf = pd.read_csv("sales.csv")
Certaines colonnes, avec de vraies datespd.read_csv("sales.csv", usecols=["date", "city", "sales"], parse_dates=["date"])
Utiliser une colonne comme indexpd.read_csv("sales.csv", index_col="id")
Tabulation ou autre séparateurpd.read_csv("sales.tsv", sep="\t")
Traiter d'autres marqueurs comme manquantspd.read_csv("sales.csv", na_values=["n/a", "-"])
Lire seulement les premières lignespd.read_csv("sales.csv", nrows=1000)
Lire une feuille Excel (nécessite openpyxl)pd.read_excel("report.xlsx", sheet_name="2026")
Lire des enregistrements JSONpd.read_json("records.json")
Lire depuis une base SQLpd.read_sql("SELECT * FROM orders", conn)
Écrire un CSV sans l'indexdf.to_csv("clean.csv", index=False)
Écrire en Excel ou Parquetdf.to_excel("clean.xlsx", index=False), df.to_parquet("clean.parquet")

Explorer les données

Les premiers appels à lancer sur tout nouveau jeu de données.

TâcheCode
Premières et dernières lignesdf.head(), df.tail(3)
Nombre de lignes et de colonnesdf.shape # (6, 7)
Types des colonnes et valeurs non nullesdf.info()
Statistiques des colonnes numériquesdf.describe()
Résumé de toutes les colonnesdf.describe(include="all")
Noms et types des colonnesdf.columns, df.dtypes
Compter chaque valeurdf["city"].value_counts()
Proportion de chaque valeurdf["city"].value_counts(normalize=True)
Valeurs distinctes et leur nombredf["city"].unique(), df["city"].nunique()
Valeurs manquantes par colonnedf.isna().sum()
Échantillon aléatoire de lignesdf.sample(3, random_state=0)
Corrélation des colonnes numériquesdf.corr(numeric_only=True)

Sélectionner des colonnes et des lignes

loc sélectionne par étiquette et inclut la fin d'une tranche. iloc sélectionne par position et l'exclut.

TâcheCode
Une colonne, en Seriesdf["age"]
Plusieurs colonnes, en DataFramedf[["name", "age"]]
Lignes et colonnes par étiquettedf.loc[0:2, ["name", "age"]]
Lignes et colonnes par positiondf.iloc[0:2, 0:3]
Une seule valeurdf.at[0, "age"], df.iat[0, 3]
Dernière lignedf.iloc[-1]
Colonnes d'un type donnédf.select_dtypes(include="number")
Colonnes de texte (pandas 3)df.select_dtypes(include="str")
Colonnes selon leur nomdf.filter(like="sal"), df.filter(regex="^(age|salary)$")
Retrouver des lignes via une colonnedf.set_index("name").loc["Ada", "salary"]
Revenir à un index 0, 1, 2df.reset_index(drop=True)
Supprimer des colonnes ou des lignesdf.drop(columns=["email"]), df.drop(index=[0, 1])

Filtrer des lignes

Mets chaque condition entre parenthèses et combine-les avec & (et), | (ou) et ~ (non).

TâcheCode
Lignes qui vérifient une conditiondf[df["age"] > 30]
Les deux conditionsdf[(df["age"] > 30) & (df["city"] == "Oslo")]
L'une ou l'autre conditiondf[(df["city"] == "Oslo") | (df["salary"] > 6000)]
Valeur dans une listedf[df["city"].isin(["Oslo", "Rome"])]
Valeur absente d'une listedf[~df["city"].isin(["Oslo", "Rome"])]
Entre deux valeurs, bornes inclusesdf[df["age"].between(30, 40)]
Filtrer avec une requête textedf.query("age > 30 and city == 'Oslo'")
Utiliser une variable dans une requêtemin_age = 30 df.query("age > @min_age")
Le texte contientdf[df["name"].str.contains("e", case=False)]
Valeurs manquantes ou présentesdf[df["age"].isna()], df[df["age"].notna()]
Filtrer les lignes et choisir les colonnesdf.loc[df["age"] > 30, ["name", "salary"]]
Les n premières ou dernières lignesdf.nlargest(3, "salary"), df.nsmallest(2, "age")
Lignes avec une valeur répétéedf[df.duplicated(subset=["city"], keep=False)]

Trier et classer

TâcheCode
Trier par une colonnedf.sort_values("salary")
Les plus grands d'aborddf.sort_values("salary", ascending=False)
Trier par plusieurs colonnesdf.sort_values(["city", "salary"], ascending=[True, False])
Valeurs manquantes en premierdf.sort_values("age", na_position="first")
Trier par l'indexdf.sort_index()
Classer les valeurs, 1 = la plus hautedf["salary"].rank(ascending=False)

Ajouter et modifier des colonnes

Les opérations sur une colonne entière sont rapides. N'utilise apply que si aucune méthode intégrée ne fait l'affaire.

TâcheCode
Nouvelle colonne à partir d'autresdf["bonus"] = df["salary"] * 0.1
Ajouter une colonne dans une chaînedf.assign(bonus=lambda d: d["salary"] * 0.1)
Valeur selon une conditiondf["level"] = np.where(df["age"] >= 40, "senior", "junior")
Valeur selon plusieurs conditionsdf["band"] = np.select([df["age"] < 30, df["age"] < 45], ["young", "mid"], default="senior")
Modifier les valeurs qui vérifient une conditiondf.loc[df["city"] == "Lima", "salary"] = 4000
Remplacer des valeurs via un dictdf["country"] = df["city"].map({"Oslo": "NO", "Rome": "IT", "Lima": "PE"})
Appliquer une fonction à une colonnedf["salary"].apply(lambda x: round(x, -3))
Appliquer une fonction à chaque celluledf[["age", "salary"]].map(lambda x: x / 1000)
Renommer des colonnesdf.rename(columns={"salary": "pay"})
Changer le type d'une colonnedf["salary"].astype("float64")
Texte en nombres, valeurs invalides en NaNpd.to_numeric(s, errors="coerce")
Nombres en classes étiquetéespd.cut(df["age"], bins=[0, 30, 45, 120], labels=["young", "mid", "senior"])
Nombres en groupes de même taillepd.qcut(df["salary"], q=4, labels=False)
Boucler sur les lignes (lent, en dernier recours)for row in df.itertuples(): print(row.name, row.salary)

Valeurs manquantes et nettoyage

Les nombres manquants s'affichent NaN, les dates manquantes NaT. Chacun de ces appels renvoie un nouvel objet, alors affecte le résultat.

TâcheCode
Part de valeurs manquantes par colonnedf.isna().mean()
Supprimer les lignes avec une valeur manquantedf.dropna()
Supprimer les lignes sans colonne clédf.dropna(subset=["age"])
Remplir avec une valeur par colonnedf.fillna({"age": df["age"].median()})
Remplir depuis la ligne précédente ou suivantedf["age"].ffill(), df["age"].bfill()
Combler les trous par interpolationdf["age"].interpolate()
Transformer des marqueurs en valeurs manquantesdf.replace(["n/a", "-", ""], np.nan)
Supprimer les lignes en doubledf.drop_duplicates()
Garder la dernière ligne par clédf.drop_duplicates(subset=["city"], keep="last")
Nettoyer les noms de colonnesdf.columns = df.columns.str.strip().str.lower().str.replace(" ", "_")
Plafonner les valeurs extrêmesdf["salary"].clip(lower=4000, upper=6000)
Type category pour du texte répétédf["city"] = df["city"].astype("category")

Colonnes de texte (.str)

Dans pandas 3, les colonnes de texte ont le dtype str par défaut. Les méthodes .str s'appliquent à toute la colonne, et les valeurs manquantes restent manquantes.

TâcheCode
Majuscules, minuscules ou initialesdf["name"].str.upper(), df["name"].str.lower(), df["name"].str.title()
Supprimer les espacesdf["name"].str.strip()
Remplacer du textedf["email"].str.replace("mail.com", "example.com")
Remplacer avec une regexdf["email"].str.replace(r"@.*", "", regex=True)
Contient, commence pardf["name"].str.contains("a"), df["name"].str.startswith("E")
Longueur de chaque valeurdf["name"].str.len()
Premiers caractèresdf["name"].str[:2]
Découper en colonnesdf["email"].str.split("@", expand=True)
Extraire avec un groupe de regexdf["email"].str.extract(r"@(\w+)")
Concaténer des colonnes de textedf["name"] + " (" + df["city"] + ")"
Compléter des nombres avec des zérosdf["salary"].astype("str").str.zfill(6)
Le nouveau dtype textedf["name"].dtype # str

Dates et heures

L'accesseur .dt fonctionne sur les colonnes datetime. Un index de dates trié (ts ci-dessous) permet de découper par texte et de rééchantillonner.

TâcheCode
Convertir une colonne en datetimedf["date"] = pd.to_datetime(df["date"])
Convertir avec un format exactpd.to_datetime(["03/01/2026", "15/01/2026"], format="%d/%m/%Y")
Année, mois, nom du jourdf["date"].dt.year, df["date"].dt.month, df["date"].dt.day_name()
Regrouper les dates par moisdf["date"].dt.to_period("M")
Jours entre deux dates(pd.Timestamp("2026-12-31") - df["date"]).dt.days
Ajouter des jours ou des moisdf["date"] + pd.Timedelta(days=30), df["date"] + pd.DateOffset(months=1)
Lignes dans une plage de datesdf[df["date"].between("2021-01-01", "2022-12-31")]
Index de dates, découpé par textets = df.set_index("date").sort_index() ts.loc["2021":"2022"]
Total par moists["salary"].resample("ME").sum()
Moyenne hebdomadaire ; "QE" par trimestre, "YE" par ants["salary"].resample("W").mean()
Moyenne mobilets["salary"].rolling(3).mean()
Variation par rapport à la ligne précédentets["salary"].diff(), ts["salary"].pct_change()
Décaler les valeurs d'une ligne vers le basts["salary"].shift(1)
Cumults["salary"].cumsum()
Définir et convertir les fuseaux horairests.index.tz_localize("UTC").tz_convert("Europe/Oslo")

Grouper et agréger

groupby répartit les lignes par clé, applique une fonction à chaque groupe et combine les résultats.

TâcheCode
Moyenne par groupedf.groupby("city")["salary"].mean()
Plusieurs statistiques d'un coupdf.groupby("city")["salary"].agg(["mean", "max", "count"])
Colonnes de résultat nomméesdf.groupby("city").agg(avg_pay=("salary", "mean"), people=("name", "count"))
Grouper par deux colonnesdf.groupby(["city", "team"])["salary"].sum()
Garder les clés en colonnesdf.groupby("city", as_index=False)["salary"].mean()
Nombre de lignes par groupedf.groupby("city").size()
Résultat du groupe sur chaque lignedf["city_avg"] = df.groupby("city")["salary"].transform("mean")
Garder seulement certains groupesdf.groupby("city").filter(lambda g: len(g) >= 2)
Ligne du maximum par groupedf.loc[df.groupby("city")["salary"].idxmax()]
Les n premières lignes par groupedf.sort_values("salary", ascending=False).groupby("city").head(2)
Numéroter les lignes de chaque groupedf.groupby("city").cumcount()
Boucler sur les groupesfor city, group in df.groupby("city"): print(city, len(group))
Filtrer, grouper et trier en une chaîne(df.query("age > 30") .groupby("city", as_index=False) .agg(avg_pay=("salary", "mean")) .sort_values("avg_pay", ascending=False))

Pivoter et restructurer

Le format long a une ligne par observation. Le format large répartit une variable sur plusieurs colonnes.

TâcheCode
Tableau croisé dynamiquedf.pivot_table(index="city", columns="team", values="salary", aggfunc="mean", fill_value=0)
Tableau croisé avec totauxdf.pivot_table(index="city", values="salary", aggfunc="sum", margins=True)
Compter les combinaisonspd.crosstab(df["city"], df["team"])
Proportions par lignepd.crosstab(df["city"], df["team"], normalize="index")
Large vers longlong = df.melt(id_vars="name", value_vars=["age", "salary"], var_name="field", value_name="value")
Long vers largelong.pivot(index="name", columns="field", values="value")
Niveau d'index interne en colonnesdf.groupby(["city", "team"])["salary"].sum().unstack(fill_value=0)
Une ligne par élément de listepd.DataFrame({"id": [1, 2], "tags": [["a", "b"], ["c"]]}).explode("tags")
Encodage one-hot d'une colonnepd.get_dummies(df["team"], prefix="team")
Échanger lignes et colonnesdf.T

Combiner des DataFrames

concat empile les tables, merge les joint sur des colonnes clés, comme en SQL.

TâcheCode
Empiler des lignespd.concat([df_2025, df_2026], ignore_index=True)
Placer côte à côtepd.concat([left, right], axis=1)
Joindre sur une colonne cléorders.merge(customers, on="customer_id", how="left")
Types de jointurehow="inner", "left", "right", "outer"
Clés aux noms différentsorders.merge(users, left_on="customer_id", right_on="id")
Vérifier la jointure et marquer la source de chaque ligneorders.merge(customers, on="customer_id", how="left", validate="many_to_one", indicator=True)
Joindre sur l'indexleft.join(right, how="inner")
Lignes sans correspondance dans une autre tableorders[~orders["customer_id"].isin(customers["customer_id"])]

Tracer avec pandas

pandas dessine avec Matplotlib. Chaque appel de tracé renvoie un ax Matplotlib, que tu peux continuer à personnaliser.

TâcheCode
Courbe d'une sériets["salary"].plot()
Courbe à partir de deux colonnesdf.plot(x="date", y="salary")
Diagramme en barres d'un résumédf.groupby("city")["salary"].mean().plot.bar()
Barres horizontales triéesdf["city"].value_counts().sort_values().plot.barh()
Histogrammedf["salary"].plot.hist(bins=20)
Nuage de pointsdf.plot.scatter(x="age", y="salary")
Boîte à moustaches par groupedf.boxplot(column="salary", by="city")
Titre et libellé d'axeax = df.plot(x="date", y="salary", title="Salary") ax.set_ylabel("EUR")
Afficher ou enregistrer le graphiqueplt.show(), ax.figure.savefig("salary.png", dpi=150)

pandas 3 : anciennes syntaxes et quoi écrire maintenant

Le code copié d'anciens tutoriels échoue souvent ou déclenche des avertissements avec pandas 3. Écris plutôt la version de la colonne pandas 3.

Tâchepandas 3Ancienne syntaxe
Fonction sur chaque celluledf.map(f)df.applymap(f)
Remplir depuis la ligne précédentedf.ffill()df.fillna(method="ffill")
Ajouter des lignespd.concat([df, new_rows])df.append(new_rows)
Rééchantillonner en fin de moists["salary"].resample("ME").sum()resample("M")
Dates horairespd.date_range("2026-01-01", periods=24, freq="h")freq="H"
Modifier une seule valeurdf.loc[0, "age"] = 37df["age"][0] = 37
Modifier un sous-ensemble filtréhigh = df[df["salary"] > 5000] high["salary"] = 0high = df[df["salary"] > 5000].copy()
Est-ce une colonne de texte ?df["name"].dtype == "str"df["name"].dtype == object

Le code pandas qu'un data analyst utilise tous les jours, classé par tâche : créer et charger des données, les explorer, sélectionner et filtrer des lignes, ajouter des colonnes, gérer les valeurs manquantes, travailler avec du texte et des dates, grouper et agréger, restructurer, fusionner et tracer. Chaque ligne donne un court extrait à copier-coller, avec une phrase qui explique ce qu'il fait.

Tout est écrit pour pandas 3, la version utilisée par Coddy : les colonnes de texte utilisent le nouveau dtype str, le Copy-on-Write est toujours actif, et les API supprimées comme applymap et fillna(method=...) n'apparaissent que dans le tableau des anciennes syntaxes. Les exemples utilisent un DataFrame df avec les colonnes name, city, team, age, salary, date et email. Tu débutes en Python ? Commence par l'aide-mémoire Python et le playground Python, et garde les aide-mémoire NumPy, Matplotlib et scikit-learn à portée de main.

FAQ de l'aide-mémoire pandas

Cet aide-mémoire pandas est-il gratuit ?
Oui. Cet aide-mémoire pandas est entièrement gratuit, sans inscription. Ajoute-le à tes favoris ou imprime-le en PDF depuis ton navigateur, et reviens dès que tu as besoin de l'appel exact pour un groupby, un merge ou un tableau croisé dynamique.
Quelle version de pandas cet aide-mémoire couvre-t-il ?
pandas 3. Les colonnes de texte utilisent le nouveau dtype str, le Copy-on-Write est toujours actif, et les appels supprimés dans pandas 3 (applymap, fillna(method=...), append, les alias de fréquence M et H) n'apparaissent que dans le dernier tableau, à côté de ce qu'il faut écrire à la place. Presque tous les extraits fonctionnent aussi avec pandas 2.2, sauf les lignes qui reposent sur le dtype str ou sur le Copy-on-Write.
Quelle est la différence entre loc et iloc ?
loc sélectionne par étiquette, c'est-à-dire les valeurs de l'index et les noms de colonnes, et une tranche comme df.loc[0:2] inclut sa fin. iloc sélectionne par position entière, comme une liste Python, donc df.iloc[0:2] renvoie les deux premières lignes et exclut la fin. Utilise loc avec une condition pour filtrer les lignes et choisir les colonnes en une seule étape : df.loc[df["age"] > 30, ["name"]].
Comment filtrer un DataFrame sur plusieurs conditions ?
Mets chaque condition entre parenthèses et relie-les avec & pour et, | pour ou, et ~ pour non : df[(df["age"] > 30) & (df["city"] == "Oslo")]. Les and et or de Python ne fonctionnent pas sur des colonnes entières. Pour les filtres longs, df.query("age > 30 and city == 'Oslo'") est plus lisible.
Quelle est la différence entre merge, join et concat ?
merge combine deux DataFrames sur des colonnes clés, comme une jointure SQL, avec how="inner", "left", "right" ou "outer". join est un raccourci qui fusionne sur l'index. concat ne fait correspondre aucune clé : il empile les tables les unes sur les autres, ou côte à côte avec axis=1.
Pourquoi mon affectation ne modifie-t-elle pas le DataFrame ?
Depuis pandas 3, avec le Copy-on-Write, chaque sélection se comporte comme une copie. Une affectation chaînée comme df["age"][0] = 37 modifie un objet temporaire et laisse df intact. Écris-la plutôt en un seul appel loc : df.loc[0, "age"] = 37. Les méthodes comme dropna et fillna renvoient aussi un nouvel objet, alors affecte le résultat.
Puis-je exécuter du code pandas en ligne ?
Oui. Le playground Matplotlib gratuit exécute Python avec pandas, NumPy, Matplotlib et scikit-learn dans ton navigateur : tu peux coller n'importe quel extrait de cet aide-mémoire et le lancer sans rien installer. Le cours Machine Learning de Coddy enseigne pandas pas à pas, de ton premier DataFrame jusqu'aux données qui alimentent un modèle.
Illustration des langages de programmation de Coddy

Apprenez Pandas avec Coddy

COMMENCER