1) Pourquoi analyser des données avec Python ?
Écosystème riche : pandas (manipulation), matplotlib (graphiques bas-niveau),
seaborn (graphiques statistiques), scikit-learn (ML), etc.
Lisibilité & productivité : syntaxe claire, notebooks interactifs.
Reproductibilité : scripts/Notebooks versionnables, pipelines.
Interopérabilité : CSV, Excel, SQL, Parquet…
Communauté & exemples : beaucoup de ressources et de bonnes pratiques.
Objectif du module : savoir charger, explorer, transformer et visualiser des données
avec des graphiques pertinents, interpréter les résultats et raconter une histoire claire.
2) Installation & préparation de l’environnement
a) Créer un environnement (recommandé)
# ---> Pour creer : Sous Windows / macOS / Linux
python -m venv .venv
# ---> Pour activer activer
1 / 17
# Windows (PowerShell)
.venv\Scripts\Activate.ps1
# macOS/Linux (bash/zsh)
source .venv/bin/activate
Pas l'objet de la formation, mais une règle de bonne pratique
b) Installer les bibliothèques
pip install pandas matplotlib seaborn jupyter
c) Lancer Jupyter (optionnel)
--> Via le terminal
jupyter lab
# ou
jupyter notebook
# ou en
Via Visual Studio Code (vscode)
Via Anaconda
2 / 17
Via Google Colab
Cas d'étude : Célibataires dans le monde (50 000 lignes)
Jeu de données utilisé : celibataires_monde_v2.csv / celibataires_monde_v2.xlsx
Variables clés : genre , annee_naissance , age_2025 , taille_cm , poids_kg , imc ,
milieu , etat_emploi , niveau_etudes , revenu_annuel_usd , pays_origine ,
pays_residence , ville_residence , etc.
Lien : [Link]
export=view&id=12Vt48j7tBaS99QSmyvBepW3vFlMtryA7
3) Importer les bibliothèques & charger le jeu de
données
Pandas
3 / 17
import pandas as pd
import numpy as np
import [Link] as plt
import seaborn as sns
# Option d’affichage
pd.set_option("display.max_columns", None)
# Chemin vers le fichier (adapter si besoin)
CSV_PATH = "celibataires_monde_v2.csv"
# Chargement
df = pd.read_csv(CSV_PATH)
# Aperçu
[Link]()
4 / 17
NB : "[Link]
export=view&id=12Vt48j7tBaS99QSmyvBepW3vFlMtryA7"
À vérifier :
[Link] # nombre de lignes/colonnes
[Link] # noms des colonnes
[Link]() # types des colonnes + valeurs manquantes
[Link](numeric_only=True) # stats descriptives numériques
4) Sélection & filtrage dans un DataFrame
a) Sélection par étiquette vs. position
# 1 cellule
[Link][0, "prenom"] # étiquette (index/colonnes)
[Link][0, 0] # position (ligne 0, col 0)
# ligne(s) complète(s)
[Link][0] # ligne index 0
[Link][:5] # 5 premières lignes
b) Sélection de colonnes
df["genre"].head()
df[ ["prenom", "genre", "pays_residence"] ].head()
c) Filtrer (requêtes simples)
# 1 condition
femmes = df[df["genre"] == "F"]
5 / 17
# plusieurs conditions (ET & OU)
femmes_urbain = df[(df["genre"] == "F") & (df["milieu"] == "urbain")]
hauts_revenus = df[(df["revenu_annuel_usd"] > 50000) |
(df["niveau_etudes"].isin(["supérieur", "postgrad"]))]
# via .query (syntaxe compacte)
femmes_france = [Link]("genre == 'F' and pays_residence == 'France'")
d) Trier et échantillonner
df.sort_values(by="revenu_annuel_usd", ascending=False).head(10)
[Link](5, random_state=42)
5) Créer de nouvelles colonnes & exporter
a) Exemple : âge à partir de l’année de naissance
from datetime import datetime
current_year = [Link]().year # ou 2025
df["age"] = current_year - df["annee_naissance"]
df[["annee_naissance", "age"]].head()
b) Catégoriser l’IMC (OMS, simplifié)
bins = [0, 18.5, 25, 30, [Link]]
labels = ["insuffisance", "normal", "surpoids", "obésité"]
df["imc_cat"] = [Link](df["imc"], bins=bins, labels=labels, right=False)
df["imc_cat"].value_counts(dropna=False)
c) Détecter migration (origine ≠ résidence)
df["est_migrant"] = (df["pays_origine"] != df["pays_residence"]).astype(int)
6 / 17
df["est_migrant"].mean() # ≈ 0.037 (3.7 %) dans ce jeu synthétique
d) Exporter (format au choix)
# CSV
df.to_csv("celibataires_enrichi.csv", index=False, encoding="utf-8")
# Excel
df.to_excel("celibataires_enrichi.xlsx", index=False)
# Parquet (rapide/compact, nécessite pyarrow)
# pip install pyarrow
# df.to_parquet("celibataires_enrichi.parquet", index=False)
6) Choisir le bon graphique
Objectif Type de variable Bon choix de graphique
Part/proportion Catégorielle (faible Barres, pie (avec parcimonie)
modalités)
Distribution Numérique Histogramme, KDE (densité),
Boxplot, Violin
7 / 17
Objectif Type de variable Bon choix de graphique
Comparer des Catégorielle × Numérique Barres (avec erreur), Box/Violin
moyennes
Relation 2 numériques Nuage de points (scatter), Ligne
(série temporelle)
Classement Catégorielle (beaucoup Barres horizontales triées
de modalités)
Corrélations Plusieurs numériques Matrice de corrélation + Heatmap
Conseil : préférez les barres pour des catégories ; évitez les camemberts quand il y a
trop de modalités (>5).
7) Visualisation avec Matplotlib
a) Anatomie : Figure, Axes, API pyplot
fig, ax = [Link](figsize=(8, 4)) # crée une figure et 1 axe
[Link]([1,2,3], [2,3,2], marker="o")
ax.set_title("Exemple simple")
ax.set_xlabel("X")
ax.set_ylabel("Y")
[Link](True, alpha=0.3)
[Link]()
Figure : zone globale du dessin.
Axes : région de tracé (où apparaissent les données).
[Link] , [Link] , [Link] , etc. : méthodes pour dessiner.
ax.set_* : configurer titres/labels/limites.
b) Subplots (plusieurs graphiques)
fig, axs = [Link](nrows=1, ncols=2, figsize=(12, 4), sharey=False)
axs[0].hist(df["age"], bins=20)
axs[0].set_title("Distribution de l'âge")
moyenne_taille = [Link]("genre")["taille_cm"].mean().sort_values()
8 / 17
axs[1].bar(moyenne_taille.index, moyenne_taille.values)
axs[1].set_title("Taille moyenne par genre")
for i, v in enumerate(moyenne_taille.values):
axs[1].annotate(f"{v:.1f} cm", (i, v), xytext=(0,3), textcoords="offset
points", ha="center")
plt.tight_layout()
[Link]()
c) Graphiques de base (Matplotlib)
Histogramme
[Link](figsize=(6,4))
[Link](df["revenu_annuel_usd"], bins=50)
[Link]("Distribution des revenus (USD)")
[Link]("Revenu annuel (USD)")
[Link]("Nombre de personnes")
[Link]("log") # utile si distribution très étalée
[Link]()
Barres
top_pays = df["pays_residence"].value_counts().head(10)[: -1] # du 10e au 1er
[Link](figsize=(7,5))
[Link](top_pays.index, top_pays.values)
[Link]("Top 10 pays de résidence")
[Link]("Effectif")
9 / 17
plt.tight_layout()
[Link]()
Ligne
age_mean_by_birth = [Link]("annee_naissance")["taille_cm"].mean()
[Link](figsize=(7,4))
[Link](age_mean_by_birth.index, age_mean_by_birth.values, marker=".")
[Link]("Taille moyenne par année de naissance")
[Link]("Année de naissance")
[Link]("Taille moyenne (cm)")
[Link]()
Camembert (avec parcimonie)
parts = df["genre"].value_counts()
[Link](figsize=(4,4))
[Link]([Link], labels=[Link], autopct="%1.1f%%", startangle=90)
[Link]("Répartition par genre")
plt.tight_layout()
[Link]()
Boxplot
[Link](figsize=(6,4))
[Link]([[Link][df["genre"]=="F","imc"], [Link][df["genre"]=="M","imc"]],
labels=["F","M"])
10 / 17
[Link]("IMC par genre")
[Link]("IMC")
[Link]()
Interprétation (exemples) :
Histogramme des revenus : distribution étalée/à droite (log-échelle utile).
Barres top pays : compare les effectifs par pays.
Ligne taille vs année de naissance : tendance globale (attention aux cohortes).
Boxplot IMC par genre : comparer médiane, étendue et valeurs extrêmes.
8) Personnaliser vos graphiques
fig, ax = [Link](figsize=(7,4))
vals = df["heures_sport_semaine"].value_counts().sort_index()
[Link]([Link](str), [Link])
ax.set_title("Heures de sport par semaine")
ax.set_xlabel("Heures")
ax.set_ylabel("Effectif")
[Link](axis="y", alpha=0.3)
for x, y in zip([Link], [Link]):
[Link](str(y), (x, y), xytext=(0,3), textcoords="offset points",
ha="center")
plt.tight_layout()
[Link]()
À connaître :
Titres & labels : set_title , set_xlabel , set_ylabel
Axes : set_xlim , set_ylim , set_xticks , set_yticks , tick_params(rotation=...)
Légende : [Link]() (après label= dans les tracés)
Annoter : [Link](text, xy=(x,y), ...)
Grille : [Link](True, alpha=0.3)
11 / 17
Mise en page : plt.tight_layout()
9) Visualisation exploratoire avec Seaborn
seaborn simplifie les graphiques statistiques et gère bien les groupes ( hue ) et les
incertitudes ( ci ).
a) Distributions & densité
[Link](data=df, x="age", bins=25, kde=True)
[Link]("Distribution de l'âge avec densité")
[Link]()
Paramètres clés : data , x / y , bins , kde (courbe de densité).
b) Comptages catégoriels
[Link](data=df, x="genre")
[Link]("Effectifs par genre")
[Link]()
Paramètres : x (catégorie), hue (sous-groupes), order (tri).
c) Barres agrégées (moyenne, médiane…)
[Link](data=df, x="genre", y="taille_cm", estimator=[Link], ci=95)
[Link]("Taille moyenne par genre (±95% CI)")
[Link]()
estimator : fonction d’agrégation ( [Link] , [Link] )
ci : intervalle de confiance (ou errorbar=('ci', 95) sur versions récentes)
d) Boxplot / Violin (distributions par groupe)
[Link](data=df, x="genre", y="imc")
[Link]("IMC par genre (boxplot)")
[Link]()
12 / 17
[Link](data=df, x="milieu", y="revenu_annuel_usd", cut=0)
[Link]("log")
[Link]("Revenu annuel par milieu (échelle log)")
[Link]()
Astuce : yscale("log") si forte asymétrie.
e) Nuage de points & tendance
[Link](data=[Link](5000, random_state=1), x="taille_cm",
y="poids_kg", hue="genre", alpha=0.6)
[Link]("Relation taille/poids (échantillon)")
[Link]()
[Link](data=[Link](5000, random_state=2), x="age", y="imc",
hue="genre", scatter_kws={"alpha":0.3})
[Link]("IMC vs âge, droite de régression")
[Link]()
lmplot : tendance linéaire par groupe ( hue ).
f) Matrice de corrélation & heatmap
num_cols = ["age", "taille_cm", "poids_kg", "imc", "heures_sport_semaine",
"revenu_annuel_usd"]
corr = df[num_cols].corr(numeric_only=True)
[Link](corr, annot=True, fmt=".2f")
[Link]("Matrice de corrélation (numériques)")
[Link]()
13 / 17
Interprétation : valeurs proches de 1 (corrélation forte positive), -1 (forte négative).
g) Comparaisons multi-facettes ( catplot , FacetGrid )
[Link](data=df, x="genre", y="revenu_annuel_usd", col="milieu",
kind="bar", ci=None)
[Link]("log")
[Link]()
col / row : facettes par sous-échantillons.
10) Mini-analyses guidées (exemples)
Âge : distribution centrée autour de 30–40 ans (selon tirage). Intéressant de
comparer urbain vs rural :
[Link](data=df, x="age", hue="milieu", common_norm=False)
[Link]("Âge — densité par milieu")
[Link]()
IMC par genre : boxplot ou violin pour voir médianes/dispersion :
[Link](data=df, x="genre", y="imc")
[Link]("IMC par genre")
[Link]()
Répartition par pays : Top 10 (barres horizontales) :
top10 = df["pays_residence"].value_counts().head(10)
[Link](x=[Link], y=[Link], orient="h")
[Link]("Top 10 pays de résidence")
14 / 17
[Link]("Effectif")
[Link]("Pays")
[Link]()
Sport & IMC : relation simple :
[Link](data=[Link](8000, random_state=0),
x="heures_sport_semaine", y="imc", alpha=0.3)
[Link]("IMC vs heures de sport/semaine")
[Link]()
Attente : corrélation faible/négative (plus de sport → IMC légèrement plus bas), mais
corrélation ≠ causalité.
Revenus par niveau d’études :
[Link](data=df, x="niveau_etudes", y="revenu_annuel_usd",
showfliers=False)
[Link]("log")
[Link]("Revenu annuel par niveau d'études (échelle log)")
[Link]()
11) Bonnes pratiques
Toujours décrire le jeu, les hypothèses et les limites (ici données synthétiques).
Nettoyage : valeurs manquantes, doublons, types ( astype ), normalisation.
Visualisations lisibles : titres, labels, échelles, tri, unités claires.
Échantillonnage sur grands volumes pour tracer rapidement.
Séparer exploration (EDA) et production (rapports/dashboards).
Sauvegarder vos figures en SVG/PNG avec [Link]("[Link]", dpi=150,
bbox_inches="tight") .
12) Exercices pratiques
Filtrer les personnes célibataires urbaines de moins de 30 ans et afficher leur
répartition par pays (barres triées).
15 / 17
Créer imc_cat puis comparer la répartition par genre (barres empilées ou
regroupées).
Visualiser le revenu médian par pays (Top 10) avec échelle log.
Explorer la relation âge vs revenu_annuel_usd par milieu ( hue /facettes).
Exporter un sous-échantillon propre en CSV et Excel.
13) Références utiles (générales)
[Link] : sélection, groupby, pivot, merge, datetime.
matplotlib : anatomie Figure/Axes, annotations, échelles ( log ), subplots.
seaborn : gramme statistique haut niveau ( histplot , boxplot , barplot , catplot ,
pairplot , heatmap ).
Note éthique : ce jeu de données est synthétique (généré). Les caractéristiques ne
sont pas corrélées aux nationalités/genres pour éviter les stéréotypes.
Boilerplate de départ (copier/coller)
import pandas as pd, numpy as np, [Link] as plt, seaborn as sns
df = pd.read_csv("celibataires_monde_v2.csv")
df["age"] = [Link]().year - df["annee_naissance"]
[Link]()
Type de Méthode principale Paramètres clés
graphique
Courbe (Line [Link](x, y, color, x , y (données) ; color ( 'r' , 'g' ,
plot) linestyle, marker) '#123456' ), linestyle ( '-' , '--' ,
':' ), marker ( 'o' , 's' , 'x' )
Nuage de [Link](x, y, s, c, x, y ; s (taille des points) ; c
points (Scatter) alpha) (couleur ou colormap) ; alpha
(transparence)
Histogramme [Link](data, bins, data (valeurs) ; bins (nombre de
color, alpha, density) classes) ; color ; alpha ;
density=True (normalisation en
probabilité)
Barres [Link](x, height, x (catégories) ; height (valeurs) ;
verticales width, color) width (largeur) ; color
Barres [Link](y, width, y (catégories) ; width (valeurs) ;
horizontales color) color
Secteurs (Pie [Link](data, labels, data (valeurs) ; labels ;
chart) autopct, colors) autopct='%1.1f%%' (pourcentages) ;
colors
Boxplot (boîte [Link](data, vert, data (liste ou array) ;
à moustaches) patch_artist) vert=True/False (orientation) ;
patch_artist=True (remplissage)
16 / 17
Type de Méthode principale Paramètres clés
graphique
Aires (Area plt.fill_between(x, y1, x ; y1 (borne inférieure) ; y2 (borne
plot) y2, color, alpha) supérieure ou 0) ; color ; alpha
Step plot [Link](x, y, where) x , y ; where='mid'/'pre'/'post'
(courbe en (position des sauts)
escalier)
Polar / Radar [Link](theta, r) theta (angle en radians) ; r (rayon)
Error bar [Link](x, y, x , y ; yerr (erreurs verticales) ;
(Barres yerr, xerr, fmt) xerr (erreurs horizontales) ; fmt
d’erreur) (format : '-o' , 's' )
Heatmap [Link](data, cmap, data (matrice 2D) ; cmap='viridis' ;
simple interpolation) interpolation='nearest'
(Matrice)
Graphique 3D – ax.plot3D(x, y, z) x, y, z (coordonnées 3D)
Courbe
Graphique 3D – ax.scatter3D(x, y, z, x, y, z ; c (couleur) ; s (taille)
Nuage c, s)
Graphique 3D – ax.plot_surface(X, Y, X, Y (maillage avec [Link] ) ;
Surface Z, cmap) Z (valeurs) ; cmap
17 / 17