Après avoir présenté la logique de Pandas dans le chapitre précédent, ce chapitre vise à illustrer les fonctionalités du package à partir de données d’émissions de gaz à effet de serre de l’Ademe.

Author

Lino Galiana

Published

July 1, 2023

Les exemples de ce TP sont visualisables sous forme de Jupyter Notebooks:

Download nbviewer Onyxia Onyxia
Binder Open In Colab githubdev

Dans cette série d’exercices Pandas, nous allons découvrir comment manipuler plusieurs jeux de données avec Python.

Si vous êtes intéressés par R, une version très proche de ce TP est disponible dans ce cours.

Dans ce tutoriel, nous allons utiliser deux sources de données :

La librairie pynsee n’est pas installée par défaut avec Python. Avant de pouvoir l’utiliser, il est nécessaire de l’installer :

!pip install xlrd
!pip install pynsee

Toutes les dépendances indispensables étant installées, il suffit maintenant d’importer les librairies qui seront utilisées pendant ces exercices :

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import pynsee
import pynsee.download

Importer les données

Import d’un csv de l’Ademe

L’URL d’accès aux données peut être conservé dans une variable ad hoc :

url = "https://koumoul.com/s/data-fair/api/v1/datasets/igt-pouvoir-de-rechauffement-global/convert"

L’objectif du premier exercice est de se familiariser à l’import et l’affichage de données avec Pandas.

Premières manipulations de données

Le chapitre précédent évoquait quelques manipulations traditionnelles de données. Les principales sont rappelées ici :

Sélectionner des colonnes Renommer des colonnes

Créer de nouvelles colonnes Sélectionner des lignes

Réordonner le DataFrame

La cheatsheet suivante est très pratique puisqu’elle illustre ces différentes fonctions. Il est recommandé de régulièrement la consulter :

Cheasheet Pandas

L’objectif du prochain exercice est de se familiariser aux principales manipulations de données sur un sous-ensemble de la table des émissions de gaz carbonique.

A la question 5, quand on ordonne les communes exclusivement à partir de la variable transports_total, on obtient ainsi:

code_insee Commune transports transports_international dep transports_total
31108 77291 LE MESNIL-AMELOT 133834.090767 3.303394e+06 77 3.437228e+06
31099 77282 MAUREGARD 133699.072712 3.303394e+06 77 3.437093e+06
31111 77294 MITRY-MORY 89815.529858 2.202275e+06 77 2.292090e+06

A la question 6, on obtient ce classement :

code_insee Commune transports transports_international dep transports_total
4438 13096 SAINTES-MARIES-DE-LA-MER 271182.758578 0.000000 13 271182.758578
4397 13054 MARIGNANE 245375.418650 527360.799265 13 772736.217915
11684 31069 BLAGNAC 210157.688544 403717.366279 31 613875.054823

Import des données de l’Insee

En ce qui concerne nos informations communales, on va utiliser l’une des sources de l’Insee les plus utilisées : les données Filosofi. Afin de faciliter la récupération de celles-ci, nous allons utiliser le package communautaire pynsee :

On va utiliser les données Filosofi (données de revenus) au niveau communal de 2016. Ce n’est pas la même année que les données d’émission de CO2, ce n’est donc pas parfaitement rigoureux, mais cela permettra tout de même d’illustrer les principales fonctionnalités de Pandas

Le point d’entrée principal de la fonction pynsee est la fonction download_file.

Le code pour télécharger les données est le suivant :

from pynsee.download import download_file
filosofi = download_file("FILOSOFI_COM_2016")

Le DataFrame en question a l’aspect suivant :

CODGEO LIBGEO NBMENFISC16 NBPERSMENFISC16 MED16 PIMP16 TP6016 TP60AGE116 TP60AGE216 TP60AGE316 ... PPEN16 PPAT16 PPSOC16 PPFAM16 PPMINI16 PPLOGT16 PIMPOT16 D116 D916 RD16
14422 38419 Saint-Martin-de-Clelles 74 164 17992.38095238095 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
32388 83071 La Londe-les-Maures 4904 10282.5 21663.04347826087 55 12 NaN NaN 19 ... 47.4 14.1 3.3 1.1 1.4 0.9 -17.6 11672.916666666668 37875.5 3.244733178654292
19989 54554 Vaudigny NaN NaN NaN NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
9947 28026 Baudreville 106 258 21569.666666666664 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
5683 17125 Courcelles 211 476.5 21718 NaN NaN NaN NaN NaN ... NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN

5 rows × 29 columns

Pandas a géré automatiquement les types de variables. Il le fait relativement bien, mais une vérification est toujours utile pour les variables qui ont un statut spécifique.

Pour les variables qui ne sont pas en type float alors qu’elles devraient l’être, on modifie leur type.

filosofi.loc[:, filosofi.columns[2:]] = (
  filosofi.loc[:, filosofi.columns[2:]]
  .apply(pd.to_numeric, errors='coerce')
)

Un simple coup d’oeil sur les données donne une idée assez précise de la manière dont les données sont organisées. On remarque que certaines variables de filosofi semblent avoir beaucoup de valeurs manquantes (secret statistique) alors que d’autres semblent complètes. Si on désire exploiter filosofi, il faut faire attention à la variable choisie.

Notre objectif à terme va être de relier l’information contenue entre ces deux jeux de données. En effet, sinon, nous risquons d’être frustré : nous allons vouloir en savoir plus sur les émissions de gaz carbonique mais seront très limités dans les possibilités d’analyse sans ajout d’une information annexe issue de filosofi.

Les indices

Les indices sont des éléments spéciaux d’un DataFrame puisqu’ils permettent d’identifier certaines observations. Il est tout à fait possible d’utiliser plusieurs indices, par exemple si on a des niveaux imbriqués.

Pour le moment, on va prendre comme acquis que les codes communes (dits aussi codes Insee) permettent d’identifier de manière unique une commune. Un exercice ultérieur permettra de s’en assurer.

Pandas propose un système d’indice qui permet d’ordonner les variables mais également de gagner en efficacité sur certains traitements, comme des recherches d’observations. Le prochain exercice illustre cette fonctionnalité.

En pratique, l’utilisation des indices en Pandas peut être piégeuse, notamment lorsqu’on associe des sources de données.
Il est plutôt recommandé de ne pas les utiliser ou de les utiliser avec parcimonie, cela pourra éviter de mauvaises surprises.

Restructurer les données

Quand on a plusieurs informations pour un même individu ou groupe, on retrouve généralement deux types de structure de données :

  • format wide : les données comportent des observations répétées, pour un même individu (ou groupe), dans des colonnes différentes
  • format long : les données comportent des observations répétées, pour un même individu, dans des lignes différentes avec une colonne permettant de distinguer les niveaux d’observations

Un exemple de la distinction entre les deux peut être pris à l’ouvrage de référence d’Hadley Wickham, R for Data Science:

Données long et wide

L’aide mémoire suivante aidera à se rappeler les fonctions à appliquer si besoin :

Le fait de passer d’un format wide au format long (ou vice-versa) peut être extrêmement pratique car certaines fonctions sont plus adéquates sur une forme de données ou sur l’autre.

En règle générale, avec Python comme avec R, les formats long sont souvent préférables. Les formats wide sont plutôt pensés pour des tableurs comme Excel ou on dispose d’un nombre réduit de lignes à partir duquel faire des tableaux croisés dynamiques.

Le prochain exercice propose donc une telle restructuration de données. Les données de l’ADEME, et celles de l’Insee également, sont au format wide. Le prochain exercice illustre l’intérêt de faire la conversion long \(\to\) wide avant de faire un graphique.

Combiner les données

Travail préliminaire

Jusqu’à présent lorsque nous avons produit des statistiques descriptives, celles-ci étaient univariées, c’est-à-dire que nous produisions de l’information sur une variable mais nous ne la mettions pas en lien avec une autre. Pourtant, on est rapidement amené à désirer expliquer certaines statistiques agrégées à partir de caractéristiques issues d’une autre source de données. Cela implique donc d’associer des jeux de données, autrement dit de mettre en lien deux jeux de données présentant le même niveau d’information.

On appelle ceci faire un merge ou un join. De manière illustrée, ceci revient à effectuer ce type d’opération :

Avant de faire ceci, il est néanmoins nécessaire de s’assurer que les variables communes entre les bases de données présentent le bon niveau d’information.

Ce petit exercice permet de se rassurer car les libellés dupliqués sont en fait des noms de commune identiques mais qui ne sont pas dans le même département. Il ne s’agit donc pas d’observations dupliquées. On peut donc se fier aux codes communes, qui eux sont uniques.

Associer des données

Une information que l’on cherche à obtenir s’obtient de moins en moins à partir d’une unique base de données. Il devient commun de devoir combiner des données issues de sources différentes.

Nous allons ici nous focaliser sur le cas le plus favorable qui est la situation où une information permet d’apparier de manière exacte deux bases de données (autrement nous serions dans une situation, beaucoup plus complexe, d’appariement flou). La situation typique est l’appariement entre deux sources de données selon un identifiant individuel ou un identifiant de code commune, ce qui est notre cas.

Il est recommandé de lire ce guide assez complet sur la question des jointures avec R qui donne des recommandations également utiles en Python.

Dans le langage courant du statisticien, on utilise de manière indifférente les termes merge ou join. Le deuxième terme provient de la syntaxe SQL. Quand on fait du Pandas, on utilise plutôt la commande merge.

A l’issue de la question 5, le graphique des corrélations est le suivant :

<Axes: ylabel='index'>

Exercices bonus

Les plus rapides d’entre vous sont invités à aller un peu plus loin en s’entraînant avec des exercices bonus qui proviennent du site de Xavier Dupré. 3 notebooks en lien avec numpy et pandas vous y sont proposés :

  1. Calcul Matriciel, Optimisation : énoncé / corrigé
  2. DataFrame et Graphes : énoncé / corrigé
  3. Pandas et itérateurs : énoncé / corrigé
Back to top

Footnotes

  1. Par manque d’imagination, on est souvent tenté d’appeler notre dataframe principal df ou data. C’est souvent une mauvaise idée puisque ce nom n’est pas très informatif quand on relit le code quelques semaines plus tard. L’autodocumentation, approche qui consiste à avoir un code qui se comprend de lui-même, est une bonne pratique et il est donc recommandé de donner un nom simple mais efficace pour connaître la nature du dataset en question.↩︎

  2. Idéalement, il serait nécessaire de s’assurer que cette jointure n’introduit pas de biais. En effet, comme nos années de référence ne sont pas forcément identiques, il peut y avoir un mismatch entre nos deux sources. Le TP étant déjà long, nous n’allons pas dans cette voie. Les lecteurs intéressés pourront effectuer une telle analyse en exercice supplémentaire.↩︎

Citation

BibTeX citation:
@book{galiana2023,
  author = {Galiana, Lino},
  title = {Python Pour La Data Science},
  date = {2023},
  url = {https://pythonds.linogaliana.fr/},
  doi = {10.5281/zenodo.8229676},
  langid = {en}
}
For attribution, please cite this work as:
Galiana, Lino. 2023. Python Pour La Data Science. https://doi.org/10.5281/zenodo.8229676.