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.
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).
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).
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.
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
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
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: objectAccès aux données par index avec loc
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: objectPour 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.
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 22print(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 22Sé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 [ ... ]).
# 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.
# 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 triascending: un booléen pour indiquer si le tri est ascendant ou descendant (par défautTrue)
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ées | Tri ascendant | Tri descendant |
|---|---|---|
| Numériques | Ordre croissant | Ordre décroissant |
| Textuelles | Ordre alphabétique (A → Z) | Ordre anti-alphabétique (Z → A) |
| Dates | Ordre 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 :
# 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 :
df["city"] = ["Paris", "Lyon", "Marseille", "Bordeaux"]Modifier une colonne
Pour modifier une colonne, on affecte de nouvelles valeurs à la clé du DataFrame :
# Nouvelles valeurs
df["city"] = ["Strasbourg", "Lille", "Pau", "Toulouse"]
# Appliquer une opération sur toutes les valeurs
df["age"] = df["age"] + 1Supprimer une colonnne
Pour supprimer une colonne, on peut utiliser la méthode drop :
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
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.
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 NaNLes fonctions fillna() et dropna() permettent respectivement de remplacer les valeurs manquantes et de supprimer les lignes contenant des valeurs manquantes.
# 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().
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: float64Lors 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().
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 25Pour effectuer un groupBy sur plusieurs colonnes, il suffit de spécifier ces colonnes dans une liste.
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: float64Pivot 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().
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ètre | Rôle |
|---|---|
values | Colonne(s) sur laquelle on applique le calcul |
index | Colonnes qui deviennent les lignes du tableau |
columns | Colonnes qui deviennent les colonnes du tableau |
aggfunc | Fonction d’agrégation (mean, sum, count, etc.) |
margins | Ajoute 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.0Pour remplacer les valeurs manquantes, on peut utiliser le paramètre fill_value.
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.
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.0Pour appliquer plusieurs fonctions d’agrégation, on peut utiliser une liste.
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 80000Pour 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.
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.0Top 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.
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 48Concaté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.
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 30Jointures 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.
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 150Par 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 SQL | Description |
|---|---|---|
inner (default) | INNER JOIN | Garde seulement les correspondances |
left | LEFT JOIN | Garde tout le DataFrame de gauche |
right | RIGHT JOIN | Garde tout le DataFrame de droite |
outer | FULL JOIN | Garde 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.
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.0Exploration, 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 !