DataFrames pandas en Python : sélectionner, filtrer, grouper et résumer

La boîte à outils du quotidien — charger un tableau, le découper, le restructurer et répondre à des questions avec groupby.

Apprenez les DataFrames pandas en Python : créer et inspecter un DataFrame, sélectionner des colonnes, filtrer des lignes avec des masques booléens et .loc/.iloc, ajouter des colonnes avec .assign, grouper et résumer avec groupby, trier les résultats et gérer les valeurs manquantes avec dropna/fillna.

Date de publication

26 juin 2026

Modifié

7 juillet 2026

AstucePoints clés
  • Un DataFrame est un tableau ; une Series est une seule colonne. Chaque colonne que vous extrayez est une Series, et une Series porte un index, exactement comme le tableau dont elle provient.
  • Sélectionnez des colonnes avec [], filtrez des lignes avec un masque booléen. df["col"] récupère une colonne ; df[df["col"] > x] conserve les lignes où le test vaut True.
  • .loc fonctionne par étiquette, .iloc par position. Les confondre est l’erreur pandas la plus fréquente — apprenez la règle une fois et elle cesse de vous piéger.
  • .assign ajoute ou transforme des colonnes sans modifier l’original, ce qui garde vos chaînes propres et lisibles.
  • groupby(...).agg(...) répond à « pour chaque groupe, quel est… ? » — l’outil de référence pour résumer des données, à l’image de GROUP BY en SQL.
  • Les valeurs manquantes (NaN) se propagent tant que vous ne les traitez pas — dropna() les supprime, fillna() les remplace. Choisissez l’un ou l’autre en connaissance de cause.

Introduction

pandas est le tableau de données de Python. Si vous avez déjà utilisé un tableur, un data.frame R ou une table SQL, vous en connaissez déjà la forme : des lignes d’enregistrements, des colonnes de champs. pandas vous offre ce tableau en Python, plus une manière rapide et expressive de le découper, de le restructurer et de l’interroger. C’est la première chose que la plupart des travaux sur données importent et la dernière qu’ils abandonnent.

Cette leçon est la boîte à outils du quotidien — les opérations auxquelles vous recourez dans presque chaque analyse : charger un tableau, le regarder, en extraire des colonnes et des lignes, ajouter des colonnes calculées, grouper-et-résumer, trier et gérer les valeurs manquantes que les vraies données comportent toujours. La leçon est livrée avec un petit CSV penguins, ainsi rien n’est à télécharger et aucun seaborn n’est à installer.

Chaque résultat et chaque figure ici sont réels — et vous pouvez les exécuter vous-même sans rien installer : cliquez sur Try ▸ sous n’importe quel bloc pour l’exécuter en direct dans votre navigateur (Python démarre au premier Run, puis c’est instantané).

Series ou DataFrame

Un DataFrame est un tableau à deux dimensions. Une Series en est une seule colonne — un tableau unidimensionnel de valeurs auquel est attaché un index (les étiquettes de lignes). Quand vous extrayez une colonne d’un DataFrame, vous obtenez une Series ; quand vous en extrayez plusieurs, vous obtenez un DataFrame plus petit. Voici les deux construits à la main :

import pandas as pd

# A Series — one column of values, with an index
ages = pd.Series([22, 35, 58], name="age")
print(ages)
0    22
1    35
2    58
Name: age, dtype: int64

La colonne de gauche (0 1 2) est l’index — pandas en ajoute un entier quand vous ne fournissez pas d’étiquettes. La colonne de droite contient les données, et Name: age est le nom de la Series. Un DataFrame est un assemblage de plusieurs de ces colonnes alignées sur un index partagé :

import pandas as pd

people = pd.DataFrame({
    "name": ["Ada", "Linus", "Grace"],
    "age":  [22, 35, 58],
    "lang": ["Python", "C", "COBOL"],
})
print(people)
    name  age    lang
0    Ada   22  Python
1  Linus   35       C
2  Grace   58   COBOL

Chaque colonne est une Series ; en en réextrayant une, on le confirme :

print(type(people["age"]))   # a Series
print(type(people[["age"]])) # a DataFrame (note the double brackets)
<class 'pandas.core.series.Series'>
<class 'pandas.core.frame.DataFrame'>

Notez la règle des crochets qui piège tout le monde au début : df["age"] (crochets simples) renvoie une Series ; df[["age"]] (une liste de noms) renvoie un DataFrame. Demandez une liste de colonnes, vous récupérez un tableau.

Charger un jeu de données depuis un CSV

Une vraie pratique demande de vraies données. Cette leçon est livrée avec un petit CSV penguins placé à côté d’elle — des mesures physiques pour trois espèces de manchots — qui se charge donc directement depuis le disque avec pd.read_csv, sans téléchargement ni seaborn.

import pandas as pd

penguins = pd.read_csv("penguins.csv")
print(penguins.head())
  species     island  bill_length_mm  bill_depth_mm  flipper_length_mm  \
0  Adelie  Torgersen            39.1           18.7              181.0   
1  Adelie  Torgersen            39.5           17.4              186.0   
2  Adelie  Torgersen            40.3           18.0              195.0   
3  Adelie  Torgersen             NaN            NaN                NaN   
4  Adelie  Torgersen            36.7           19.3              193.0   

   body_mass_g     sex  
0       3750.0    Male  
1       3800.0  Female  
2       3250.0  Female  
3          NaN     NaN  
4       3450.0  Female  

head() affiche les cinq premières lignes. Nous avons des colonnes catégorielles (species, island, sex) et des colonnes numériques (mesures du bec et de la nageoire, body_mass_g). Le NaN que vous pourriez repérer est le marqueur pandas d’une valeur manquante — nous les traiterons à la fin.

Inspecter avant de calculer

Regardez toujours avant de vous lancer. Quatre méthodes vous disent presque tout d’un tableau fraîchement chargé : sa taille, le type de ses colonnes, un résumé numérique et un aperçu des lignes.

print("shape (rows, columns):", penguins.shape)
print()
print("dtypes:")
print(penguins.dtypes)
shape (rows, columns): (344, 7)

dtypes:
species               object
island                object
bill_length_mm       float64
bill_depth_mm        float64
flipper_length_mm    float64
body_mass_g          float64
sex                   object
dtype: object

shape indique 344 lignes et 7 colonnes. dtypes montre le type de chaque colonne — object pour le texte (les colonnes catégorielles), float64 pour les mesures. Si une colonne de nombres arrive en object, c’est le signe que quelque chose cloche (une chaîne « N/A » égarée, par exemple) avant que le moindre calcul ne dérape.

describe() donne un résumé numérique rapide — effectif, moyenne, dispersion et quartiles pour chaque colonne numérique d’un coup :

print(penguins.describe().round(1))
       bill_length_mm  bill_depth_mm  flipper_length_mm  body_mass_g
count           342.0          342.0              342.0        342.0
mean             43.9           17.2              200.9       4201.8
std               5.5            2.0               14.1        802.0
min              32.1           13.1              172.0       2700.0
25%              39.2           15.6              190.0       3550.0
50%              44.4           17.3              197.0       4050.0
75%              48.5           18.7              213.0       4750.0
max              59.6           21.5              231.0       6300.0

Lisez d’abord la ligne count : elle vaut 342, et non 344, pour les colonnes numériques — deux lignes ont des mesures manquantes. La masse corporelle moyenne est d’environ 4202 g, allant de 2700 g à 6300 g. Cet unique appel signale déjà les données manquantes et l’échelle de chaque variable.

Sélectionner des colonnes

Extrayez une seule colonne par son nom (une Series) ou plusieurs en passant une liste (un DataFrame) :

# One column -> Series
print(penguins["species"].head(3))
0    Adelie
1    Adelie
2    Adelie
Name: species, dtype: object
# Several columns -> DataFrame
cols = penguins[["species", "body_mass_g", "flipper_length_mm"]]
print(cols.head(3))
  species  body_mass_g  flipper_length_mm
0  Adelie       3750.0              181.0
1  Adelie       3800.0              186.0
2  Adelie       3250.0              195.0

La première renvoie la Series species ; la seconde renvoie un tableau de trois colonnes. C’est la règle des crochets vue plus haut, appliquée à de vraies données.

Filtrer des lignes avec un masque booléen

Pour conserver les lignes qui remplissent une condition, écrivez la condition sur une colonne — cela produit une Series de True/False — puis indexez le DataFrame avec elle. pandas conserve les lignes True.

# The condition is itself a Series of booleans
mask = penguins["body_mass_g"] > 5000
print(mask.head(5))
0    False
1    False
2    False
3    False
4    False
Name: body_mass_g, dtype: bool
# Use the mask to keep only the heavy penguins
heavy = penguins[penguins["body_mass_g"] > 5000]
print(heavy.shape)
print(heavy[["species", "body_mass_g"]].head())
(61, 7)
    species  body_mass_g
221  Gentoo       5700.0
223  Gentoo       5700.0
224  Gentoo       5400.0
227  Gentoo       5200.0
229  Gentoo       5150.0

61 manchots pèsent plus de 5000 g, et les premiers affichés sont tous des Gentoo — la plus grande espèce. Combinez les conditions avec & (et) / | (ou), en entourant chaque condition de parenthèses (la priorité des opérateurs l’exige) :

big_gentoo = penguins[(penguins["species"] == "Gentoo") & (penguins["body_mass_g"] > 5500)]
print(big_gentoo.shape[0], "heavy Gentoo penguins")
28 heavy Gentoo penguins

Pour l’appartenance à un ensemble de valeurs, .isin() se lit mieux que d’enchaîner des | :

two_islands = penguins[penguins["island"].isin(["Biscoe", "Dream"])]
print(two_islands["island"].value_counts())
island
Biscoe    168
Dream     124
Name: count, dtype: int64

.loc et .iloc : étiquette ou position

Le filtrage par crochets convient pour des lignes-par-condition, mais pour sélectionner des lignes et des colonnes ensemble, vous voulez .loc ou .iloc. La règle est courte et vaut la peine d’être mémorisée :

  • .loc[rows, cols] utilise des étiquettes — valeurs d’index et noms de colonnes.
  • .iloc[rows, cols] utilise des positions entières — comme l’indexation de listes, borne de fin exclue.
# .loc — by label: rows with index 0..3, named columns
print(penguins.loc[0:3, ["species", "body_mass_g"]])
  species  body_mass_g
0  Adelie       3750.0
1  Adelie       3800.0
2  Adelie       3250.0
3  Adelie          NaN
# .iloc — by position: first 4 rows, first 3 columns
print(penguins.iloc[0:4, 0:3])
  species     island  bill_length_mm
0  Adelie  Torgersen            39.1
1  Adelie  Torgersen            39.5
2  Adelie  Torgersen            40.3
3  Adelie  Torgersen             NaN

Deux différences à remarquer. Avec .loc, 0:3 inclut l’étiquette 3 (le découpage par étiquette est inclusif) ; avec .iloc, 0:4 s’arrête avant la position 4 (le découpage par position est exclusif, comme en Python normal). Et .loc nomme ses colonnes tandis que .iloc les compte. .loc accepte aussi un masque booléen, qui est la manière explicite et sans avertissement de filtrer :

print(penguins.loc[penguins["body_mass_g"] > 6000, ["species", "body_mass_g"]])
    species  body_mass_g
237  Gentoo       6300.0
253  Gentoo       6050.0

Ajouter ou transformer des colonnes avec .assign

.assign() renvoie un nouveau DataFrame avec une colonne ajoutée ou remplacée, en laissant l’original intact. Cela le rend sûr au sein des chaînes et facile à lire. Ici, nous ajoutons la masse corporelle en kilogrammes :

penguins2 = penguins.assign(body_mass_kg=penguins["body_mass_g"] / 1000)
print(penguins2[["species", "body_mass_g", "body_mass_kg"]].head(3))
  species  body_mass_g  body_mass_kg
0  Adelie       3750.0          3.75
1  Adelie       3800.0          3.80
2  Adelie       3250.0          3.25

La nouvelle colonne body_mass_kg vient se placer à côté de l’original. Vous pouvez aussi calculer à partir d’autres colonnes — ici une surface approximative du bec, et une colonne indicatrice dans le même appel :

penguins2 = penguins.assign(
    bill_area=penguins["bill_length_mm"] * penguins["bill_depth_mm"],
    is_heavy=penguins["body_mass_g"] > 4500,
)
print(penguins2[["species", "bill_area", "is_heavy"]].head(3))
  species  bill_area  is_heavy
0  Adelie     731.17     False
1  Adelie     687.30     False
2  Adelie     725.40     False

Comme .assign ne modifie pas penguins, vous évitez le piège de l’indexation chaînée qui déclenche SettingWithCopyWarning (plus de détails ci-dessous).

groupby et agrégation

C’est l’opération que vous utiliserez le plus. groupby découpe le tableau en groupes selon une ou plusieurs colonnes, applique un résumé à chacun, puis recoud les résultats — la même idée que le GROUP BY de SQL ou le group_by() |> summarise() de R. Commencez avec une clé de groupe et une statistique :

mean_mass = penguins.groupby("species")["body_mass_g"].mean().round(0)
print(mean_mass)
species
Adelie       3701.0
Chinstrap    3733.0
Gentoo       5076.0
Name: body_mass_g, dtype: float64

Masse corporelle moyenne par espèce : Adelie ~3701 g, Chinstrap ~3733 g, Gentoo ~5076 g — les Gentoo sont clairement les poids lourds. Notez que le résultat est une Series (une valeur par groupe) parce que nous avons sélectionné une seule colonne.

Pour plusieurs statistiques à la fois, ou plusieurs colonnes, utilisez .agg() :

summary = penguins.groupby("species").agg(
    n=("body_mass_g", "size"),
    mean_mass=("body_mass_g", "mean"),
    mean_flipper=("flipper_length_mm", "mean"),
).round(1)
print(summary)
             n  mean_mass  mean_flipper
species                                
Adelie     152     3700.7         190.0
Chinstrap   68     3733.1         195.8
Gentoo     124     5076.0         217.2

La forme d’agrégation nommée (new_name=("column", "function")) vous donne des noms de colonnes propres et auto-documentés. La ligne de chaque espèce affiche son effectif, sa masse corporelle moyenne et sa longueur de nageoire moyenne. Groupez selon deux clés pour une ventilation plus fine :

by_species_sex = (
    penguins
    .groupby(["species", "sex"])["body_mass_g"]
    .mean()
    .round(0)
)
print(by_species_sex)
species    sex   
Adelie     Female    3369.0
           Male      4043.0
Chinstrap  Female    3527.0
           Male      3939.0
Gentoo     Female    4680.0
           Male      5485.0
Name: body_mass_g, dtype: float64

Le résultat a un index de lignes à deux niveaux (MultiIndex) — chaque combinaison espèce/sexe. Les mâles sont plus lourds que les femelles au sein de chaque espèce, un écart que nous tracerons dans un instant.

Trier les résultats

sort_values ordonne les lignes selon une ou plusieurs colonnes ; ascending=False place les plus grandes en premier. Triez le résumé par espèce selon la masse moyenne :

print(summary.sort_values("mean_mass", ascending=False))
             n  mean_mass  mean_flipper
species                                
Gentoo     124     5076.0         217.2
Chinstrap   68     3733.1         195.8
Adelie     152     3700.7         190.0

Gentoo arrive en tête, comme attendu. Pour trier le tableau d’origine et voir les individus les plus lourds :

heaviest = penguins.sort_values("body_mass_g", ascending=False)
print(heaviest[["species", "sex", "body_mass_g"]].head(3))
    species   sex  body_mass_g
237  Gentoo  Male       6300.0
253  Gentoo  Male       6050.0
297  Gentoo  Male       6000.0

Les trois premiers sont tous des Gentoo mâles, entre 6300 et 6050 g.

Gérer les valeurs manquantes

Les vraies données ont des trous. pandas les marque NaN, et — c’est important — NaN se propage : il n’est égal à rien, et la plupart des opérations qui le touchent renvoient NaN sauf instruction contraire. D’abord, repérez-les :

print(penguins.isna().sum())
species               0
island                0
bill_length_mm        2
bill_depth_mm         2
flipper_length_mm     2
body_mass_g           2
sex                  11
dtype: int64

sex a 11 valeurs manquantes et les quatre colonnes de mesures en ont 2 chacune. Deux façons de les gérer, choisies en connaissance de cause :

# Option 1 — drop any row with a missing value
complete = penguins.dropna()
print("after dropna:", complete.shape)
after dropna: (333, 7)
# Option 2 — fill missing sex with a label, keep every row
filled = penguins.assign(sex=penguins["sex"].fillna("unknown"))
print(filled["sex"].value_counts())
sex
Male       168
Female     165
unknown     11
Name: count, dtype: int64

dropna() laisse 333 lignes complètes (les 11 lignes au sex manquant ont disparu). fillna("unknown") conserve les 344 et étiquette les trous à la place. Utilisez dropna quand les lignes sont inutilisables ; utilisez fillna quand une valeur par défaut sensée préserve une information que vous perdriez autrement. La moyenne groupée plus haut a déjà fait ce qu’il fallait automatiquement — pandas ignore les NaN dans les agrégations comme mean(), vous obtenez donc la moyenne des valeurs qui existent.

Un graphique propre d’un résumé groupé

Terminons en transformant le résumé espèce-par-sexe en figure. Nous calculons la masse corporelle moyenne par espèce et par sexe (en supprimant d’abord les lignes au sex manquant), nous la restructurons en tableau large avec pivot_table, et nous laissons le .plot.bar() intégré de pandas (qui utilise matplotlib) dessiner des barres appariées.

import matplotlib.pyplot as plt

# Mean body mass per species and sex, reshaped to wide form for grouped bars
wide = (
    penguins
    .dropna(subset=["sex"])
    .pivot_table(index="species", columns="sex", values="body_mass_g", aggfunc="mean")
)

ax = wide.plot.bar(color=["#3a86d4", "#f4a259"], figsize=(7, 4.5), rot=0)
ax.set_xlabel("Species")
ax.set_ylabel("Mean body mass (g)")
ax.set_title("Mean penguin body mass by species and sex")
ax.legend(title="Sex")
plt.tight_layout()
plt.show()
Grouped bar chart of mean penguin body mass in grams by species (Adelie, Chinstrap, Gentoo) on the x-axis, with two bars per species for female and male; males are heavier in every species and Gentoo is heaviest overall, around 5500 grams for males.
Figure 1

Le graphique rend le motif immédiat : les Gentoo sont les plus lourds sur toute la ligne, et au sein de chaque espèce les mâles dépassent les femelles. Cette histoire en deux lignes — grouper, puis visualiser — constitue l’essentiel de l’analyse de données pratique.

🟢 Avec un agent IA

Apportez votre propre CSV — collez-en un df.head() et demandez à Prova « filtre les lignes qui m’intéressent, puis groupe par une colonne et donne-moi la moyenne et l’effectif par groupe » — elle écrit l’appel df[mask] + groupby(...).agg(...). Comme le runtime est ici même, vous l’exécutez et vous recoupez les tailles de groupes avec df.shape et df["col"].value_counts(), ce qui vous fait faire confiance au résumé au lieu d’accepter une réponse plausible sur parole. The runtime is the judge. Demander à Prova →

Essayez en direct

Les blocs ci-dessus ont été exécutés au moment de la génération. Modifiez celui-ci et appuyez sur Run pour manipuler les manchots vous-même — il s’exécute dans votre navigateur via Pyodide (sans installation). Ou cliquez sur Try ▸ sous n’importe quel bloc ci-dessus pour y déposer son code. Le premier Run télécharge pandas une fois (~20 Mo) — ensuite c’est mis en cache et instantané.

Problèmes courants

SettingWithCopyWarning dû à l’indexation chaînée. Écrire df[df["x"] > 0]["y"] = 1 filtre d’abord (en créant une copie temporaire) puis affecte à cette copie, de sorte que votre modification peut être silencieusement perdue. Faites le tout en un seul .loc : df.loc[df["x"] > 0, "y"] = 1. La règle empirique — si vous affectez, sélectionnez avec un seul .loc, jamais deux jeux de crochets.

Confondre .loc (étiquette) et .iloc (position). df.loc[0:3] inclut l’étiquette 3 ; df.iloc[0:3] s’arrête avant la position 3. Après un filtre ou un tri, les étiquettes d’index ne correspondent plus aux positions (penguins.iloc[0] n’est pas la ligne étiquetée 0), si bien qu’appeler .loc[0] peut saisir une autre ligne que celle attendue — ou lever une KeyError. Choisissez celui qui correspond à la manière dont vous adressez les lignes, et utilisez .reset_index(drop=True) si vous voulez réaligner étiquettes et positions.

groupby renvoyant une Series ou un DataFrame. df.groupby("g")["x"].mean() sélectionne une colonne et renvoie une Series ; df.groupby("g")[["x"]].mean() (ou .agg(...)) renvoie un DataFrame. Si une étape en aval attend un tableau et se plaint, ce double crochet ou .agg() est généralement la solution.

Questions fréquentes

Construisez une condition booléenne sur la colonne et indexez le DataFrame avec elle : df[df["body_mass_g"] > 5000] conserve chaque ligne où le test vaut True. Combinez les conditions avec & et |, en entourant chacune de parenthèses — df[(df["species"] == "Gentoo") & (df["body_mass_g"] > 5500)]. Pour une liste de valeurs autorisées, df[df["island"].isin(["Biscoe", "Dream"])] est plus propre que d’enchaîner des |.

.loc sélectionne par étiquette (valeurs d’index et noms de colonnes) et ses découpages sont inclusifs de la borne ; .iloc sélectionne par position entière et ses découpages sont exclusifs (comme en Python normal). Ainsi df.loc[0:3] renvoie quatre lignes (étiquettes 0,1,2,3) tandis que df.iloc[0:3] en renvoie trois (positions 0,1,2). Utilisez .loc quand vous adressez les lignes/colonnes par nom, .iloc quand vous les adressez par numéro. .loc accepte aussi un masque booléen, la manière recommandée de filtrer-et-affecter en une seule étape.

Utilisez groupby puis une agrégation : df.groupby("species")["body_mass_g"].mean() donne la moyenne par groupe sous forme de Series. Pour plusieurs statistiques ou des noms propres, utilisez .agg() avec des agrégations nommées : df.groupby("species").agg(n=("body_mass_g", "size"), mean_mass=("body_mass_g", "mean")). Passez une liste à groupby (par ex. ["species", "sex"]) pour ventiler selon plus d’une clé. Les agrégations ignorent les NaN automatiquement.

La manière adaptée aux chaînes est .assign, qui renvoie un nouveau DataFrame sans modifier l’original : df.assign(body_mass_kg=df["body_mass_g"] / 1000). Vous pouvez aussi affecter directement — df["body_mass_kg"] = df["body_mass_g"] / 1000 — ce qui modifie sur place. Préférez .assign au sein des chaînes de méthodes et pour éviter le SettingWithCopyWarning que l’indexation chaînée peut déclencher.

Localisez-les d’abord avec df.isna().sum(), qui compte les NaN par colonne. Choisissez ensuite : df.dropna() supprime les lignes ayant la moindre valeur manquante (ou passez subset=[...] pour ne vérifier que certaines colonnes), tandis que df.fillna(value) les remplace par une valeur par défaut que vous fournissez. Les agrégations comme mean() ignorent déjà les NaN, vous n’avez donc souvent pas besoin de nettoyer avant de résumer — mais vous devez décider si un trou doit être supprimé ou rempli.

Testez vos connaissances

Travaillez chaque tâche dans la cellule Essayez en direct ci-dessus — modifiez et exécutez.

Utilisez le jeu de données penguins (penguins = pd.read_csv("penguins.csv")) pour chaque tâche.

Tâche 1. Sélectionnez uniquement les manchots Adelie de l’île Torgersen, et indiquez combien il y en a.

Il vous faut deux conditions combinées avec &, chacune entourée de parenthèses. Le nombre de lignes est .shape[0] du résultat.

import pandas as pd
penguins = pd.read_csv("penguins.csv")

subset = penguins[(penguins["species"] == "Adelie") & (penguins["island"] == "Torgersen")]
print(subset.shape[0], "penguins")
52 penguins

Il y a 52 manchots Adelie à Torgersen.

Tâche 2. Pour chaque island, calculez la flipper_length_mm moyenne et triez les îles de la nageoire moyenne la plus longue à la plus courte.

groupby("island") puis sélectionnez flipper_length_mm et appelez .mean(). Terminez par .sort_values(ascending=False).

import pandas as pd
penguins = pd.read_csv("penguins.csv")

result = (
    penguins
    .groupby("island")["flipper_length_mm"]
    .mean()
    .round(1)
    .sort_values(ascending=False)
)
print(result)
island
Biscoe       209.7
Dream        193.1
Torgersen    191.2
Name: flipper_length_mm, dtype: float64

Biscoe a la nageoire moyenne la plus longue (~209.7 mm), parce qu’elle abrite les grands Gentoo ; Dream et Torgersen suivent.

Vérification rapide. Vous écrivez penguins[penguins["body_mass_g"] > 5000]["sex"] = "M" et pandas avertit SettingWithCopyWarning. Quelle est la réécriture correcte ?

Faites la sélection et l’affectation en un seul .loc : penguins.loc[penguins["body_mass_g"] > 5000, "sex"] = "M". La version chaînée filtre dans une copie temporaire et affecte à celle-ci, de sorte que la modification peut ne pas atteindre l’original — .loc[rows, col] cible le vrai tableau en une seule étape.

Conclusion

Vous disposez maintenant des opérations pandas qui portent l’essentiel du travail sur données : charger et inspecter un tableau, sélectionner des colonnes, filtrer des lignes avec des masques et .loc/.iloc, ajouter des colonnes avec .assign, résumer avec groupby, trier et gérer les valeurs manquantes de manière délibérée. Exercez-vous sur vos propres CSV — les gestes sont les mêmes quelles que soient les données — et laissez groupby plus un graphique rapide faire le gros du travail pour répondre aux questions.

À lire aussi : Tableaux NumPy — le moteur de tableaux sous pandas · Résumer par groupe en R — le même grouper-et-résumer en R.

Réutilisation

Citation

BibTeX
@online{2026,
  author = {},
  title = {DataFrames pandas en Python : sélectionner, filtrer, grouper
    et résumer},
  date = {2026-06-26},
  url = {https://www.datanovia.com/learn/programming/python-foundations/pandas-dataframes},
  langid = {fr}
}
Veuillez citer ce travail comme suit :
“DataFrames pandas en Python : sélectionner, filtrer, grouper et résumer.” 2026. June 26. https://www.datanovia.com/learn/programming/python-foundations/pandas-dataframes.