Pandas › Traiter des données avec Pandas

Traitez et analysez vos données efficacement avec Pandas, la bibliothèque Python incontournable pour explorer, filtrer, transformer et fusionner vos DataFrames.

Icône de calendrier
Débutant
5 chapitres
Bannière publicitaire Hostinger

Exploration et inspection

Vos données sont importées, il est temps de les explorer ! Pour cela, Pandas propose plusieurs méthodes utiles.

Afficher les premières lignes (head())

La méthode head() permet d’afficher les premières lignes du DataFrame. Cette méthode prend en paramètre le nombre de lignes à afficher (5 par défaut).

copié !
df.head() # Par défaut 5
df.head(10)

Afficher les dernières lignes (tail())

La méthode tail() permet d’afficher les dernières lignes du DataFrame. Cette méthode prend en paramètre le nombre de lignes à afficher (5 par défaut).

copié !
df.tail() # Par défaut 5
df.tail(10)

Résumé (info())

La méthode info() permet d’afficher les informations sur le DataFrame : nombre de données, définition des colonnes (nombre, types…), usage mémoire, etc.

copié !
df.info()

Statistiques descriptives (describe())

La méthode describe() affiche un résumé des statistiques descriptives du DataFrame.

Parmi ces statistiques, on retrouve pour chaque colonne numérique :

  • Nombre de valeurs (count) : le nombre de valeurs non manquantes
  • Moyenne (mean) : la valeur moyenne des données
  • Écart-type (std) : mesure de la dispersion des valeurs autour de la moyenne
  • Valeur minimale (min) : la plus petite valeur observée
  • 1er quartile (25%) : valeur sous laquelle se trouvent 25% des données
  • Médiane (50%) : valeur centrale qui sépare la moitié des données
  • 3e quartile (75%) : valeur sous laquelle se trouvent 75% des données
  • Valeur maximale (max) : la plus grande valeur observée
copié !
df.describe()

Ces indicateurs donnent une vue d’ensemble sur la distribution et la variabilité des données.

Sélection

Sélection par ligne (iloc, loc)

Pandas permet de sélectionner des données avec les accesseurs suivants :

  • iloc : sélection par index (position)
  • loc : sélection par index (label)
Accès aux données par position avec iloc
copié !
df = pd.DataFrame({
    "pseudo": ["Camille", "Milo", "Arthur", "Gaïa"],
    "age": [25, 30, 22, 48],
})

print(df.iloc[0])

On obtient en sortie :

pseudo    Camille
age            25
Name: 0, dtype: object
Accès aux données par index avec loc
copié !
df = pd.DataFrame({
    "pseudo": ["Camille", "Milo", "Arthur", "Gaïa"],
    "age": [25, 30, 22, 48],
}, index=["id1", "id2", "id3", "id4"])

print(df.loc["id1"])

On obtient en sortie :

pseudo    Camille
age            25
Name: id1, dtype: object

Pour accéder à plusieurs lignes, on pourra :

  • Spécifier les positions des lignes via une liste python (entre crochets [ ... ]).
  • Utiliser l’opérateur : pour sélectionner un intervalle.
copié !
print(df.iloc[[0, 2]])
print(df.loc[["id1", "id3"]])

On obtient en sortie :

    pseudo  age
0  Camille   25
2   Arthur   22
      pseudo  age
id1  Camille   25
id3   Arthur   22
copié !
print(df.iloc[0:3])
print(df.loc["id1":"id3"])

On obtient en sortie :

    pseudo  age
0  Camille   25
1     Milo   30
2   Arthur   22
      pseudo  age
id1  Camille   25
id2     Milo   30
id3   Arthur   22

Sélection par colonne

Si on souhaite sélectionner les données d’une colonne, on pourra spécifier la ou les colonnes via une liste python (entre crochets [ ... ]).

copié !
# Affiche la colonne "pseudo"
print(df["pseudo"])

# Affiche les colonnes "pseudo" et "age"
print(df[["pseudo", "age"]])

Filtrage

Pandas propose un puissant système de filtre en se basant sur l’écriture de conditions.

copié !
# N'affiche que les lignes où l'âge est supérieur à 25
print(df[df["age"] > 25])

# N'affiche que les lignes où le pseudo est "Camille"
print(df[df["pseudo"] == "Camille"])

Tri

Avec pandas, pour trier un DataFrame, on utilise la méthode sort_values(). Cette méthode prend en paramètre :

  • by : le nom de la colonne sur laquelle effectuer le tri
  • ascending : un booléen pour indiquer si le tri est ascendant ou descendant (par défaut True)
copié !
df = pd.DataFrame({
    "pseudo": ["Camille", "Milo", "Arthur", "Gaïa"],
    "age": [25, 30, 22, 48],
})

# Trier par âge croissant
df_sorted = df.sort_values(by='age')

# Trier par âge décroissant
df_sorted_desc = df.sort_values(by='age', ascending=False)

Selon le type de données, le tri varie ainsi :

Type de donnéesTri ascendantTri descendant
NumériquesOrdre croissantOrdre décroissant
TextuellesOrdre alphabétique (A → Z)Ordre anti-alphabétique (Z → A)
DatesOrdre chronologique (du plus ancien au plus récent)Ordre anti-chronologique (du plus récent au plus ancien)

On peut aussi trier par plusieurs colonnes :

copié !
# Trier par âge croissant et pseudo anti-alphabetique
df.sort_values(by=['age', 'pseudo'], ascending=[True, False])

Manipulation et transformation

Modifier la structure (colonnes)

Ajouter une colonne

Pour ajouter une colonne, on peut simplement affecter une liste à une nouvelle clé du DataFrame :

copié !
df["city"] = ["Paris", "Lyon", "Marseille", "Bordeaux"]

Modifier une colonne

Pour modifier une colonne, on affecte de nouvelles valeurs à la clé du DataFrame :

copié !
# Nouvelles valeurs
df["city"] = ["Strasbourg", "Lille", "Pau", "Toulouse"]

# Appliquer une opération sur toutes les valeurs
df["age"] = df["age"] + 1

Supprimer une colonnne

Pour supprimer une colonne, on peut utiliser la méthode drop :

copié !
df = df.drop("city", axis=1)

Renommer une colonne

Pour renommer une colonne, on utilise la méthode rename(), à laquelle on passe dans le paramètre columns un dictionnaire avec en :

  • Clés : les anciens noms
  • Valeurs : les nouveaux noms
copié !
df = df.rename(columns={'old_name': 'new_name'})

Nettoyage de données

Le nettoyage de données consiste à supprimer les doublons, supprimer les valeurs manquantes ou à les remplacer par une valeur par défaut.

Gestion des doublons

La fonction drop_duplicates permet de supprimer les doublons.

copié !
df = pd.DataFrame({
    "pseudo": ["Camille", "Milo", "Arthur", "Gaïa", "Camille", "Camille"],
    "age": [25, 30, 22, 48, 25, 40],
})
df = df.drop_duplicates() # Supprime les doublons (ici, l'avant-dernière "Camille" est supprimée)

Gestion des valeurs manquantes

En analyse de données, il est fréquent que des valeurs manquantes soient présentes dans un jeu de données.

Si vous lisez un DataFrame ou une Series avec des valeurs manquantes, NaN est généré dans la sortie print() de pandas.

    pseudo   age
0  Camille   NaN
1     Milo    30
2      NaN    22
3     Gaïa   NaN

Les fonctions fillna() et dropna() permettent respectivement de remplacer les valeurs manquantes et de supprimer les lignes contenant des valeurs manquantes.

copié !
# Remplace les valeurs manquantes par 0
df = df.fillna(0)

# Remplace les valeurs manquantes par l'âge moyen
df["age"] = df["age"].fillna(df["age"].mean())

# Supprime les lignes contenant des valeurs manquantes
df = df.dropna()

Groupement et agrégations

Groupement simple

Pandas nous permet de regrouper des lignes selon une colonne, puis d’appliquer un calcul sur chaque groupe. Cela est rendu possible grâce à la fonction groupby().

copié !
df = pd.DataFrame({
    "pseudo": ["Camille", "Milo", "Arthur", "Gaïa"],
    "age": [25, 30, 22, 48],
    "city": ["Paris", "Lyon", "Bordeaux", "Bordeaux"],
})

print(df.groupby("city")["age"].mean())

On obtient en sortie :

city
Bordeaux    35.0
Lyon        30.0
Paris       25.0
Name: age, dtype: float64

Lors d’un groupby(), les valeurs uniques de la colonne utilisée comme critère de regroupement deviennent les index du résultat.

Agrégations multiples

On peut appliquer plusieurs calculs en une seule fois avec la méthode agg().

copié !
print(df.groupby("city")["age"].agg(["mean", "sum", "min", "max"]))

On obtient en sortie :

          mean  sum  min  max
city
Bordeaux  35.0   70   22   48
Lyon      30.0   30   30   30
Paris     25.0   25   25   25

Pour effectuer un groupBy sur plusieurs colonnes, il suffit de spécifier ces colonnes dans une liste.

copié !
df = pd.DataFrame({
    "pseudo": ["Camille", "Camille", "Camille", "Milo"],
    "age": [25, 30, 22, 48],
    "city": ["Paris", "Bordeaux", "Bordeaux", "Bordeaux"],
})

print(df.groupby(["city", "pseudo"])["age"].mean())

On obtient en sortie :

city      pseudo 
Bordeaux  Camille    26.0
          Milo       48.0
Paris     Camille    25.0
Name: age, dtype: float64

Pivot tables

Les Pivot Tables sont des tableaux de données qui consistent à croiser des données sur plusieurs dimensions :

  • des lignes
  • des colonnes
  • une valeur à calculer

Pandas permet de créer des pivot tables avec la fonction pivot_table().

copié !
df = pd.DataFrame({
    "pseudo": ["Camille", "Milo", "Arthur", "Gaïa"],
    "age": [25, 30, 22, 48],
    "city": ["Paris", "Lyon", "Bordeaux", "Bordeaux"],
    "salary": [50000, 60000, 70000, 80000],
    "gender": ["F", "M", "M", "F"]
})

print(df.pivot_table(
    values="salary",
    index="city",
    columns="gender",
    aggfunc="mean",
    margins=True
))
ParamètreRôle
valuesColonne(s) sur laquelle on applique le calcul
indexColonnes qui deviennent les lignes du tableau
columnsColonnes qui deviennent les colonnes du tableau
aggfuncFonction d’agrégation (mean, sum, count, etc.)
marginsAjoute les totaux globaux (ligne et colonne All)

On obtient en sortie :

gender          F        M      All
city
Bordeaux  80000.0  70000.0  75000.0
Lyon          NaN  60000.0  60000.0
Paris     50000.0      NaN  50000.0
All       65000.0  65000.0  65000.0

Pour remplacer les valeurs manquantes, on peut utiliser le paramètre fill_value.

copié !
print(df.pivot_table(
    values="salary",
    index="city",
    columns="gender",
    aggfunc="mean",
    margins=True,
    fill_value=0
))

Si on veut analyser plusieurs colonnes, on peut utiliser une liste.

copié !
print(df.pivot_table(
    values=["salary", "age"],
    index="city",
    columns="gender",
    aggfunc="mean",
    margins=True,
    fill_value=0
))

On obtient en sortie :

           age                salary
gender       F     M    All        F        M      All
city
Bordeaux  48.0  22.0  35.00  80000.0  70000.0  75000.0
Lyon       0.0  30.0  30.00      0.0  60000.0  60000.0
Paris     25.0   0.0  25.00  50000.0      0.0  50000.0
All       36.5  26.0  31.25  65000.0  65000.0  65000.0

Pour appliquer plusieurs fonctions d’agrégation, on peut utiliser une liste.

copié !
print(df.pivot_table(
    values=["salary", "age"],
    index="city",
    columns="gender",
    aggfunc=["mean", "max"],
    margins=True,
    fill_value=0
))

On obtient en sortie :

          mean                                         max
           age                salary                   age         salary
gender       F     M    All        F        M      All   F   M All      F      M    All
city
Bordeaux  48.0  22.0  35.00  80000.0  70000.0  75000.0  48  22  48  80000  70000  80000
Lyon       0.0  30.0  30.00      0.0  60000.0  60000.0   0  30  30      0  60000  60000
Paris     25.0   0.0  25.00  50000.0      0.0  50000.0  25   0  25  50000      0  50000
All       36.5  26.0  31.25  65000.0  65000.0  65000.0  48  30  48  80000  70000  80000

Pour chaque colonne (ici salary et age), on applique l’ensemble des fonctions d’agrégation définies. Pour appliquer des fonctions d’agrégation différentes sur chaque colonne, on peut utiliser un dictionnaire.

copié !
print(df.pivot_table(
    values=["salary", "age"],
    index="city",
    columns="gender",
    aggfunc={
        "salary": "mean",
        "age": "max"
    },
    margins=True,
    fill_value=0
))

On obtient ainsi le salaire moyen par ville et genre, ainsi que l’âge maximum.

           age             salary
gender       F     M All        F        M      All
city
Bordeaux  48.0  22.0  48  80000.0  70000.0  75000.0
Lyon       0.0  30.0  30      0.0  60000.0  60000.0
Paris     25.0   0.0  25  50000.0      0.0  50000.0
All       48.0  30.0  48  65000.0  65000.0  65000.0

Top cette formation 🔥 On termine proprement les deux dernières parties.

Fusion et jointures

Travailler avec plusieurs sources de données, est un besoin récurrent en data.

Pandas propose deux outils principaux : concat() et merge().

Concaténation avec concat()

concat() sert à empiler des DataFrames.

copié !
df1 = pd.DataFrame({
    "pseudo": ["Camille", "Milo"],
    "age": [25, 30],
})
df2 = pd.DataFrame({
    "pseudo": ["Arthur", "Gaïa"],
    "age": [22, 48],
})

df = pd.concat([df1, df2])
print(df)

Les lignes de df2 sont ajoutées sous celles de df1.

    pseudo  age
0  Camille   25
1     Milo   30
0   Arthur   22
1     Gaïa   48
Concaténation horizontale

Par défaut, pd.concat() agit sur l’axe vertical (lignes) (axis=0).

pd.concat() permet également de concaténer des DataFrames horizontalement (colonnes) en ajoutant l’argument axis=1.

copié !
df1 = pd.DataFrame({"pseudo": ["Camille", "Milo"]})
df2 = pd.DataFrame({"age": [25, 30]})

df = pd.concat([df1, df2], axis=1)
print(df)

On obtient en sortie :

    pseudo  age
0  Camille   25
1     Milo   30

Jointures avec merge()

Si vous êtes familier avec les jointures en SQL, merge() vous paraîtra familier puisqu’il permet de faire des jointures entre plusieurs DataFrames.

copié !
users = pd.DataFrame({
    "id": [1, 2, 3, 4],
    "pseudo": ["Camille", "Milo", "Arthur", "Gaïa"],
    "age": [25, 30, 22, 48]
})

orders = pd.DataFrame({
    "user_id": [1, 1, 3, 4],
    "amount": [50, 25, 100, 150]
})

df = pd.merge(users, orders, left_on="id", right_on="user_id")
print(df)

On relie les deux DataFrames via une clé commune :

   id   pseudo  age  user_id  amount
0   1  Camille   25        1      50
1   1  Camille   25        1      25
2   3   Arthur   22        3     100
3   4     Gaïa   48        4     150

Par défaut, pd.merge() effectue une jointure interne (inner). Autrement dit, il ne garde que les lignes en relation dans les deux DataFrames.

C’est dans la pratique le comportement le plus courant.

En revanche, il existe plusieurs autres types de jointures. C’est le paramètre how qui définit le type de jointure :

ValeurÉquivalent SQLDescription
inner (default)INNER JOINGarde seulement les correspondances
leftLEFT JOINGarde tout le DataFrame de gauche
rightRIGHT JOINGarde tout le DataFrame de droite
outerFULL JOINGarde tout des deux côtés

Les jointures gauches, droites et externes auront pour effet de définir des valeurs NaN pour les lignes non en relation.

copié !
users = pd.DataFrame({
    "id": [1, 2, 3, 4],
    "pseudo": ["Camille", "Milo", "Arthur", "Gaïa"],
    "age": [25, 30, 22, 48]
})

orders = pd.DataFrame({
    "user_id": [1, 1, 3, 4],
    "amount": [50, 25, 100, 150]
})

df = pd.merge(users, orders, left_on="id", right_on="user_id", how="left")
print(df)

Ici, Milo n’a pas de commande, donc on a NaN pour son amount.

   id   pseudo  age  user_id  amount
0   1  Camille   25      1.0    50.0
1   1  Camille   25      1.0    25.0
2   2     Milo   30      NaN     NaN
3   3   Arthur   22      3.0   100.0
4   4     Gaïa   48      4.0   150.0

Exploration, filtrage, transformation, nettoyage, groupement, fusion… Vous avez désormais les bases pour manipuler des données avec Pandas. Bienvenue sur la voie de la data analyse en Python !