W3docs

Tutoriel pandas

Apprenez pandas : Series, DataFrames, filtrage, groupby, valeurs manquantes, fusion et visualisation de données avec des exemples Python clairs.

pandas est la bibliothèque Python la plus utilisée pour travailler avec des données structurées (tabulaires). Elle fournit deux structures de données fondamentales — Series et DataFrame — ainsi qu'un riche ensemble d'outils pour charger, nettoyer, transformer, agréger et visualiser des données.

Ce chapitre couvre tout ce dont vous avez besoin pour passer de zéro à productif avec pandas : installation, structures de données, lecture de fichiers, sélection et filtrage de données, gestion des valeurs manquantes, regroupement, fusion et tracé de graphiques de base.

Installer pandas

Installez pandas avec pip :

pip install pandas

Si vous souhaitez suivre les exemples de tracé plus loin dans ce chapitre, installez également Matplotlib :

pip install matplotlib

Après l'installation, importez pandas avec l'alias conventionnel pd :

import pandas as pd

Les deux structures de données fondamentales

Series

Une Series est un tableau unidimensionnel étiqueté. Chaque élément possède une valeur et une étiquette d'index correspondante (par défaut, des entiers commençant à 0).

import pandas as pd

scores = pd.Series([88.5, 92.0, 79.5, 95.0])
print(scores)

Résultat :

0    88.5
1    92.0
2    79.5
3    95.0
dtype: float64

Vous pouvez fournir des étiquettes d'index personnalisées pour rendre les données auto-descriptives :

scores = pd.Series(
    [88.5, 92.0, 79.5, 95.0],
    index=['Alice', 'Bob', 'Carol', 'Dave']
)
print(scores)
print(scores['Bob'])  # 92.0

Résultat :

Alice    88.5
Bob      92.0
Carol    79.5
Dave     95.0
dtype: float64
92.0

Une Series avec un index significatif est similaire à un dictionnaire Python, mais elle supporte les opérations vectorisées et est intégrée au reste de l'API pandas.

DataFrame

Un DataFrame est un tableau bidimensionnel avec des lignes et des colonnes étiquetées — imaginez-le comme une feuille de calcul ou une table SQL chargée dans Python. Chaque colonne est en interne une Series qui partage le même index de lignes.

Créer un DataFrame à partir d'un dictionnaire de listes

python— editable, runs on the server

Résultat :

    name  age  score
0  Alice   25   88.5
1    Bob   30   92.0
2  Carol   28   79.5
3   Dave   35   95.0

Les clés du dictionnaire deviennent les noms de colonnes ; les valeurs du dictionnaire deviennent les colonnes. L'index de lignes est par défaut 0, 1, 2, 3.

Attributs utiles pour inspecter un DataFrame juste après sa création :

Attribut / MéthodeCe qu'il retourne
df.shapeTuple de (rows, columns)
df.dtypesType de données de chaque colonne
df.columnsÉtiquettes des colonnes
df.indexÉtiquettes des lignes
df.head(n)Les n premières lignes (par défaut 5)
df.tail(n)Les n dernières lignes (par défaut 5)
df.describe()Statistiques récapitulatives pour les colonnes numériques
df.info()Noms de colonnes, types et nombre de valeurs non nulles

Lire des données depuis des fichiers

Dans de vrais projets, vous créez rarement des DataFrames à la main. pandas peut lire des dizaines de formats de fichiers.

Lire un fichier CSV

import pandas as pd

df = pd.read_csv('sales.csv')
print(df.head())
print(df.shape)   # e.g. (1000, 5)
print(df.dtypes)

pd.read_csv() infère automatiquement les types de colonnes. Options courantes :

  • sep=';' — changer le délimiteur (par défaut la virgule)
  • index_col='id' — utiliser une colonne comme index de lignes
  • parse_dates=['date'] — interpréter une colonne comme datetime
  • nrows=500 — lire uniquement les 500 premières lignes (utile pour les gros fichiers)

Lire un fichier Excel

df = pd.read_excel('report.xlsx', sheet_name='Sheet1')

Nécessite la dépendance optionnelle openpyxl : pip install openpyxl.

Écrire des données dans un fichier

df.to_csv('output.csv', index=False)     # CSV without the row index column
df.to_excel('output.xlsx', index=False)  # Excel

Sélectionner des données

Sélectionner des colonnes

Sélectionnez une seule colonne pour obtenir une Series :

ages = df['age']
print(type(ages))  # <class 'pandas.core.series.Series'>

Sélectionnez plusieurs colonnes pour obtenir un DataFrame :

subset = df[['name', 'score']]
print(subset)

Résultat :

    name  score
0  Alice   88.5
1    Bob   92.0
2  Carol   79.5
3   Dave   95.0

Sélectionner des lignes avec loc et iloc

pandas propose deux sélecteurs de lignes principaux :

  • loc — sélectionner par étiquette (valeur d'index)
  • iloc — sélectionner par position entière (base 0)
import pandas as pd

data = {
    'name':  ['Alice', 'Bob', 'Carol', 'Dave'],
    'age':   [25, 30, 28, 35],
    'score': [88.5, 92.0, 79.5, 95.0],
}
df = pd.DataFrame(data)

print(df.loc[1])          # row with index label 1
print()
print(df.iloc[0])         # first row by position
print()
print(df.loc[1:2])        # rows with labels 1 and 2 (inclusive)
print()
print(df.iloc[0:2])       # rows at positions 0 and 1 (end is exclusive)

Résultat :

name      Bob
age        30
score    92.0
Name: 1, dtype: object

name     Alice
age         25
score     88.5
Name: 0, dtype: object

   name  age  score
1   Bob   30   92.0
2  Carol   28   79.5

    name  age  score
0  Alice   25   88.5
1    Bob   30   92.0

Notez la différence : loc[1:2] est basé sur les étiquettes et inclusif des deux côtés ; iloc[0:2] est basé sur la position et exclusif à droite (comme les tranches Python classiques).

Vous pouvez également sélectionner une cellule spécifique :

print(df.loc[1, 'score'])   # 92.0  — by label
print(df.iloc[0, 2])        # 88.5  — by position

Filtrer des lignes

Filtrez les lignes en utilisant une condition booléenne entre crochets :

import pandas as pd

data = {
    'name':  ['Alice', 'Bob', 'Carol', 'Dave'],
    'age':   [25, 30, 28, 35],
    'score': [88.5, 92.0, 79.5, 95.0],
}
df = pd.DataFrame(data)

# Rows where age is greater than 28
print(df[df['age'] > 28])

Résultat :

   name  age  score
1   Bob   30   92.0
3  Dave   35   95.0

Combinez plusieurs conditions avec & (et) ou | (ou). Enveloppez toujours chaque condition entre parenthèses :

# Age > 25 AND score >= 90
print(df[(df['age'] > 25) & (df['score'] >= 90)])

Résultat :

   name  age  score
1   Bob   30   92.0
3  Dave   35   95.0

Utilisez isin() pour filtrer par une liste de valeurs :

print(df[df['name'].isin(['Alice', 'Carol'])])

Ajouter et modifier des colonnes

Ajoutez une nouvelle colonne en lui faisant une affectation :

import pandas as pd

data = {
    'name':  ['Alice', 'Bob', 'Carol', 'Dave'],
    'age':   [25, 30, 28, 35],
    'score': [88.5, 92.0, 79.5, 95.0],
}
df = pd.DataFrame(data)

# Add a column with a calculated value
df['grade'] = df['score'].apply(lambda x: 'A' if x >= 90 else 'B')
print(df)

Résultat :

    name  age  score grade
0  Alice   25   88.5     B
1    Bob   30   92.0     A
2  Carol   28   79.5     B
3   Dave   35   95.0     A

apply() exécute une fonction sur chaque élément d'une colonne. Pour une arithmétique simple, vous pouvez utiliser directement des opérations vectorisées — elles sont plus rapides qu'apply() :

df['score_scaled'] = df['score'] / 100   # no apply() needed

Renommez des colonnes avec rename() :

df = df.rename(columns={'score': 'exam_score', 'age': 'years_old'})

Supprimez une colonne avec drop() :

df = df.drop(columns=['grade'])

Trier des données

Triez un DataFrame sur une ou plusieurs colonnes avec sort_values() :

import pandas as pd

data = {
    'department': ['Eng', 'Eng', 'HR', 'HR', 'Eng'],
    'name':       ['Alice', 'Bob', 'Carol', 'Dave', 'Eve'],
    'salary':     [90000, 95000, 70000, 72000, 88000],
}
df = pd.DataFrame(data)

print(df.sort_values('salary', ascending=False))

Résultat :

  department   name  salary
1        Eng    Bob   95000
0        Eng  Alice   90000
4        Eng    Eve   88000
3         HR   Dave   72000
2         HR  Carol   70000

Triez sur plusieurs colonnes — par exemple, département en ordre croissant, puis salaire décroissant au sein de chaque département :

df_sorted = df.sort_values(['department', 'salary'], ascending=[True, False])
print(df_sorted)

Gérer les valeurs manquantes

Les jeux de données réels contiennent presque toujours des valeurs manquantes. pandas les représente sous forme de NaN (Not a Number).

import pandas as pd

data = {
    'name':  ['Alice', 'Bob', 'Carol', 'Dave'],
    'age':   [25, None, 28, 35],
    'score': [88.5, 92.0, None, 95.0],
}
df = pd.DataFrame(data)

# Count missing values per column
print(df.isnull().sum())

Résultat :

name     0
age      1
score    1
dtype: int64

Remplir les valeurs manquantes

Remplacez NaN par une valeur fixe ou une statistique :

df_filled = df.fillna({
    'age':   df['age'].mean(),    # fill with column mean
    'score': df['score'].median() # fill with column median
})
print(df_filled)

Résultat :

    name        age  score
0  Alice  25.000000   88.5
1    Bob  29.333333   92.0
2  Carol  28.000000   92.0
3   Dave  35.000000   95.0

Supprimer les lignes avec des valeurs manquantes

df_dropped = df.dropna()
print(df_dropped)

Résultat :

    name   age  score
0  Alice  25.0   88.5
3   Dave  35.0   95.0

Quand remplir et quand supprimer : supprimer des lignes fait perdre des données et peut introduire un biais si les valeurs ne sont pas manquantes au hasard. Le remplissage (imputation) est généralement préférable lorsque les données manquantes sont rares. Pour les workflows d'apprentissage automatique, consultez le chapitre Scale pour normaliser les caractéristiques numériques après imputation.

Regrouper des données

groupby() divise le DataFrame en groupes, applique une fonction à chaque groupe et combine les résultats. C'est l'équivalent pandas de GROUP BY en SQL.

import pandas as pd

data = {
    'department': ['Eng', 'Eng', 'HR', 'HR', 'Eng'],
    'name':       ['Alice', 'Bob', 'Carol', 'Dave', 'Eve'],
    'salary':     [90000, 95000, 70000, 72000, 88000],
}
df = pd.DataFrame(data)

print(df.groupby('department')['salary'].mean())

Résultat :

department
Eng    91000.0
HR     71000.0
Name: salary, dtype: float64

Appliquez plusieurs fonctions d'agrégation à la fois avec agg() :

print(df.groupby('department')['salary'].agg(['mean', 'min', 'max', 'count']))

Résultat :

               mean    min    max  count
department
Eng        91000.0  88000  95000      3
HR         71000.0  70000  72000      2

Fusionner et concaténer des DataFrames

Fusionner (comme un SQL JOIN)

Utilisez pd.merge() pour combiner deux DataFrames sur une colonne clé commune :

import pandas as pd

employees = pd.DataFrame({
    'emp_id':  [1, 2, 3],
    'name':    ['Alice', 'Bob', 'Carol'],
    'dept_id': [10, 20, 10],
})
departments = pd.DataFrame({
    'dept_id':   [10, 20],
    'dept_name': ['Engineering', 'HR'],
})

merged = pd.merge(employees, departments, on='dept_id')
print(merged)

Résultat :

   emp_id   name  dept_id    dept_name
0       1  Alice       10  Engineering
1       2    Bob       20           HR
2       3  Carol       10  Engineering

Par défaut, il s'agit d'une jointure interne (inner join) (seules les lignes avec une clé correspondante dans les deux DataFrames). Contrôlez le type de jointure avec how :

  • how='left' — toutes les lignes du DataFrame gauche, les lignes correspondantes du droit
  • how='right' — toutes les lignes du DataFrame droit, les lignes correspondantes du gauche
  • how='outer' — toutes les lignes des deux DataFrames ; NaN là où il n'y a pas de correspondance

Concaténer (empiler des DataFrames)

Utilisez pd.concat() pour empiler verticalement des DataFrames avec les mêmes colonnes :

import pandas as pd

q1 = pd.DataFrame({'name': ['Alice', 'Bob'],   'sales': [120, 95]})
q2 = pd.DataFrame({'name': ['Carol', 'Dave'],  'sales': [110, 130]})

combined = pd.concat([q1, q2], ignore_index=True)
print(combined)

Résultat :

    name  sales
0  Alice    120
1    Bob     95
2  Carol    110
3   Dave    130

ignore_index=True réinitialise l'index de lignes pour qu'il aille de 0 à 3 au lieu de répéter 0 et 1 de chaque DataFrame source.

Statistiques descriptives

pandas facilite le calcul de statistiques récapitulatives sur l'ensemble d'un DataFrame ou sur des colonnes individuelles :

import pandas as pd

data = {
    'name':  ['Alice', 'Bob', 'Carol', 'Dave'],
    'age':   [25, 30, 28, 35],
    'score': [88.5, 92.0, 79.5, 95.0],
}
df = pd.DataFrame(data)

print(df[['age', 'score']].describe())

Résultat :

             age      score
count   4.000000   4.000000
mean   29.500000  88.750000
std     4.203173   6.714412
min    25.000000  79.500000
25%    27.250000  86.250000
50%    29.000000  90.250000
75%    31.250000  92.750000
max    35.000000  95.000000

Des statistiques individuelles sont également disponibles sous forme de méthodes directes : df['score'].mean(), df['score'].std(), df['score'].median(), df['age'].max().

Visualisation de données de base

pandas s'intègre avec Matplotlib pour vous permettre de tracer directement depuis un DataFrame avec la méthode .plot(). Installez Matplotlib d'abord si ce n'est pas déjà fait : pip install matplotlib.

Graphique en ligne

import pandas as pd
import matplotlib.pyplot as plt

data = {
    'month':   ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
    'revenue': [15000, 18000, 16500, 21000, 23000],
}
df = pd.DataFrame(data)

df.plot(kind='line', x='month', y='revenue', marker='o', title='Monthly Revenue')
plt.ylabel('Revenue ($)')
plt.tight_layout()
plt.show()

Graphique en barres

df.plot(kind='bar', x='month', y='revenue', color='steelblue', title='Monthly Revenue')
plt.ylabel('Revenue ($)')
plt.xticks(rotation=0)
plt.tight_layout()
plt.show()

Valeurs courantes pour le paramètre kind :

kindType de graphique
'line'Graphique en ligne
'bar'Graphique en barres verticales
'barh'Graphique en barres horizontales
'hist'Histogramme
'box'Boîte à moustaches
'scatter'Nuage de points (nécessite x et y)
'pie'Diagramme circulaire

Pour des tracés plus avancés, consultez les chapitres Matplotlib Introduction et Matplotlib Scatter Plot.

Pièges courants

SettingWithCopyWarning : lorsque vous filtrez un DataFrame puis essayez de modifier le résultat, pandas peut vous avertir que vous modifiez une copie plutôt que l'original. Utilisez .copy() pour être explicite :

# Safe: work on an explicit copy
young = df[df['age'] < 30].copy()
young['group'] = 'junior'

Indexage chaîné : df['col'][0] = value peut ou non modifier le DataFrame original. Utilisez toujours df.loc[0, 'col'] = value pour les affectations.

Noms de colonnes avec des espaces : si une colonne est nommée "first name", vous devez utiliser la notation entre crochets — df['first name'] — et non la notation pointée (df.first name est une erreur de syntaxe).

Entier vs. flottant après fillna : remplir NaN dans une colonne entière avec un nombre promeut la colonne en float64 car NaN est un flottant. Utilisez pd.Int64Dtype() (entier nullable) si vous avez besoin de conserver la sémantique entière avec des valeurs manquantes.

Chapitres connexes

  • NumPy Tutorial — la bibliothèque de tableaux sur laquelle pandas est construit
  • Matplotlib Introduction — créer des graphiques de qualité publication à partir de vos données
  • Matplotlib Scatter Plot — visualiser les relations entre deux variables numériques
  • Data Distribution — comprendre comment les valeurs se répartissent dans un jeu de données
  • Scale — normaliser et standardiser les caractéristiques numériques avant la modélisation
  • Categorical Data — encoder les colonnes non numériques pour l'apprentissage automatique
  • Train/Test Split — diviser un DataFrame pandas en ensembles d'entraînement et de test
  • SciPy Tutorial — fonctions statistiques et scientifiques qui complètent pandas
Was this page helpful?