Traitement des données en tables

Une des utilisations principales de l’informatique de nos jours est le traitement de quantités importantes de données dans des domaines très variés :

un site de commerce en ligne peut avoir à gérer des bases données pour des dizaines de milliers d’articles en vente, de clients, de commandes ;
un hôpital doit pouvoir accéder efficacement à tous les détails de traitements de ses patients ;
etc …

Mais si les logiciels de gestion de base de données (SGDB) sont des programmes hautement spécialisés pour effectuer ce genre de tâches le plus efficacement et sûrement possible, il est facile de mettre en œuvre les opérations de base dans un langage de programmation comme Python.

Données en table

Organisées en table, les données se présentent sous la forme suivante :

En informatique, une table de données correspondent à une liste de p-uplets nommés qui partagent les mêmes descripteurs.

Exemple de p-uplet nommé (syntaxesyntaxe La syntaxe concerne le signifiant, soit ce qu'est l'énoncé. Python) :

{'Id' : 1, 'Nom' : 'NAYMAR', 'Prénom' : 'Jean'} 

En Python, on parle de Clés et de Valeurs.

 

 


Le format CSV

Le format CSV (pour comma separated values, soit en français valeurs séparées par des virgules) est un format très pratique pour représenter des données structurées.

Dans ce format, chaque ligne représente un enregistrement et, sur une même ligne, les différents champs de l’enregistrement sont réparés par une virgule (d’où le nom).

En pratique, on peut spécifier le caractère utilisé pour séparer les différents champs et on utilise fréquemment un point-virgule, une tabulation ou deux points pour cela.

 

Dans la suite, nous allons utiliser deux fichiers nommés countries.csv  et cities.csv  qui contiennent quelques données sur les différents pays et villes du monde.

Fichiers à télécharger :

Les premières lignes de countries.csv  sont :

Remarques :

  • Les valeurs sont clairement séparés par des points-virgules.
  • Comme c’est souvent le cas, la première ligne est utilisée pour indiquer le nom des différents champs : c’est l’entête.
    Dans ce cas, le premier enregistrement se trouve sur la deuxième ligne du fichier.
  • La signification des différents champs est transparente.
    à part le champ nommé Capital_Id dont les valeurs sont des numéros d’identifiants de villes que l’on trouvera dans le fichier nommé cities.csv.

 

Les tableurs (MS Excel, LibreOffice Calc, …) sont capables d’ouvrir ce genre de fichier. Il permettent de les afficher sous forme de tableau et d’en manipuler facilement les données :

 

Les données sont issues du site http://www.geonames.org et ont été légèrement simplifiées.

Bibliothèque csv 

Importation des données

Une façon de charger un fichier CSV en Python est d’utiliser la bibliothèque csv (fournie avec la distribution de Python).

Voici une portion de code permettant de charger le fichier countries.csv , avec des points-virgules comme délimitations.

 

Dans ce cas, les résultats sont stockés sous forme d’un tableau de tableaux (ou liste de listes au sens de Python).

On peut ainsi obtenir la liste des noms des champs (ligne d’en-tête) :

Puis le premier enregistrement :

Cette structure n’est pas la plus satisfaisante car le lien entre les valeurs du tableau pays[1]  et le nom des enregistrements, contenus dans pays[0] , n’est pas direct.

 

Dictionnaire ordonné

La bibliothèque csv  possède une fonction DictReader() qui retourne un objet  DictReader  : un itérateur contenant un dictionnaire ordonné ( OrderedDict) pour chaque enregistrement, la première ligne étant utilisée pour nommer les différents champs.

La conversion du dictionnaire ordonné en dictionnaire ( dict(row)) permet uniquement d’avoir un affichage plus plaisant.

 

Cette fois, on obtient un tableau de p-uplets représentés sous forme de dictionnaire :

 

Exploitation des données

Nous allons donner deux types d’utilisation simples des données que l’on vient de charger : tout d’abord, l’interrogation des données pour récupérer telle ou telle information, puis le tri des données.

Interrogations

On peut traduire en Python des questions simples.

Par exemple : « quels sont les pays où l’on paye en euro ? »

 

Activité
Pour éviter les répétitions, convertir la liste en ensemble (set) avec la fonction set() .
  • Écrire l’instruction permettant de lister les codes de toutes les monnaies qui s’appellent ‘Dollar’.
  • Écrire l’instruction permettant de lister les noms des pays de plus de 100 millions d’habitants, sous la forme (Pays, Population (en Millions d’habitants)).

 

Tris

Pour exploiter les données, il peut être intéressant de les trier. Une utilisation possible est l’obtention du classement des entrées selon tel ou tel critère. Une autre utilisation vient du fait que, comme présenté dans la partie algorithmique du programme, la recherche dichotomique dans un tableau trié est bien plus efficace que la recherche séquentielle dans un tableau quelconque.

Tri selon un unique critère

On ne peut pas directement trier le tableau pays… car cela ne veut rien dire. Il faut indiquer selon quels critères on veut effectuer ce tri.

Pour cela, on appelle la fonction sorted()  ou la méthode .sort() , avec l’argument supplémentaire key  qui est une fonction renvoyant la valeur utilisée pour le tri.

Rappel : la méthode .sort()  trie la liste en place, alors que la fonction sorted() renvoie une nouvelle liste correspondant la liste triée, la liste initiale étant laissée intacte.

 

Par exemple, si l’on veut trier les pays par leur superficie, on doit spécifier la clé 'Area' . Pour cela, on définit une fonction appropriée :

 

Ainsi, pour classer les pays par superficie décroissante, on effectue :

 

Mais un petit problème demeure. Si on récupère les noms des 5 premiers pays ainsi classés, le résultat est étonnant :

On ne s’attend pas à trouver la Corée du Sud parmi eux. La raison est que lors de l’import, tous les champs sont considérés comme des chaînes de caractères, et le tri utilise l’ordre du dictionnaire. Ainsi, de même que 'aa'  arrive avant 'b' , '10'  arrive avant '2' . Cela apparaît ici en regardant les superficies qui commencent par 998, puis par 984, par 962, etc. Pour remédier à cela, on modifie la fonction de clé :

 

On a alors le résultat espéré :

 

On peut également procéder d’une autre manière :

L’avantage est que la conversion en nombre apparait dans le résultat.

 

Activité
  • Écrire les instructions permettant d’afficher les 10 pays les moins peuplés, dans l’ordre inverse de leur population, sous la forme (pays, population)

 

Tri selon plusieurs critères

Supposons maintenant que l’on veut trier les pays selon deux critères : tout d’abord le continent, puis le nom du pays. On peut faire cela en définissant une fonction de clé qui renvoie une paire (continent, nom du pays) :

Ainsi,

 

Cependant, dans ce tri, les deux critères ont été utilisés pour un ordre croissant. Supposons maintenant que l’on veuille trier les pays par continent et, pour chaque continent, avoir les pays par population décroissante. La méthode précédente n’est pas applicable, car on a utilisé une unique clé (composée de deux éléments) pour un tri croissant.

À la place, nous allons procéder en deux étapes :

  1. trier tous les pays par populations décroissantes ;
  2. trier ensuite le tableau obtenu par continents croissants.

Ainsi :

 

Pour que cela soit possible, la fonction de tri de Python vérifie une propriété très importante : la stabilité. Cela signifie que lors d’un tri, si plusieurs enregistrements ont la même clé, l’ordre initial des enregistrements est conservé.

Ainsi, si on a trié les pays par ordre décroissant de population puis par continent, les pays d’un même continent seront regroupés en conservant l’ordre précédent, ici la population décroissante.

 

Activité
  • Écrire les instructions permettant de d’afficher les 8 pays possédant la plus grande densité de population, dans l’ordre inverse de densité, sous la forme (Pays, densité).

CORRECTION :

 

 

Conclusion

Nous l’avons vu, il est assez facile d’écrire en Python des commandes simples pour exploiter un ensemble de données.

Cependant, une utilisation plus poussée va vite donner lieu à des programmes fastidieux : notamment, pour pouvoir exploiter les capitales des pays, nous allons devoir utiliser des données présentes dans un fichier supplémentaire.

Pour remédier à ce problème, nous allons utiliser la bibliothèque pandas qui permet d’exprimer de façon simple, lisible et concise ce genre de manipulation de données.

 


Bibliothèque pandas 

La bibliothèque pandas  ( https://pandas.pydata.org/ ) ne fait pas partie de la distribution de Python, il faut donc l’installer :

 

Lecture de fichiers

De façon classique en Python, nous allons commencer par importer le module, puis charger deux fichiers CSV :

On spécifie explicitement le caractère utilisé pour délimiter les champs du fichier, ici un point-virgule.

Remarque : l’option keep_default_na=False  est nécessaire à cause de la gestion des données manquantes. Une absence est parfois précisée spécifiquement en écrivant 'NA' plutôt que de ne rien mettre. Ainsi, à la base, la lecture de 'NA' est interprété comme une donnée manquante. On est obligé de désactiver ce traitement de base pour pouvoir utiliser la valeur 'NA'  comme code de l’Amérique du Nord.

 

La fonction read_csv()  renvoie des objets de type DataFrame , qui possèdent des propriétés et des méthodes particulièrement adaptées au traitement des données.

L’affichage d’un extrait de la table sous forme de tableau est très claire :

 

La bibliothèque pandas  propose quelques commandes utiles :

  • villes.head()  affiche les premières entrées de la table ;
  • villes.sample(7)  affiche 7 enregistrements de la table pris au hasard ;
  • villes.columns  retourne la liste des champs ;
  • villes.dtypes  affiche la liste des champs avec, à chaque fois, le type de données correspondant.

Ainsi, on a :

On remarque en particulier que pandas  a reconnu que les champs latitude, longitude et population correspondent à des données numériques.

 

On peut aussi avoir des informations statistiques (bien sûr, seules celles concernant la population sont pertinentes) :

 

Enfin, on peut facilement ne conserver que les champs qui nous intéressent.

Par exemple, si l’on ne veut que les noms des villes et leurs coordonnées, on utilise :

 

Trames de données et Séries

Les tables lues dans les fichiers CSV sont stockés par pandas  sous forme de trame de données (type DataFrame). On peut les voir comme un tableau de p-uplets nommés appelés séries (type Series).

Par exemple, l’enregistrement numéro 10 (obtenu grâce à la méthode .loc()) s’obtient en exécutant :

 

et son nom s’obtient comme pour un dictionnaire :

 

On peut également obtenir l’ensemble des valeurs d’un seul champ d’une trame de données, toujours sous la forme d’une série :

 

Remarque : pandas  permet d’utiliser une syntaxe légère en n’écrivant que villes.Name  plutôt que villes['Name'] .

 

Attention, il faut différencier :

  • la série villes['Name'] ;
  • la trame de données à un seul champ villes[['Name']] .

 

Exploitation des données

Interrogations simples

Reprenons les interrogations présentées dans la première partie, et exprimons-les à l’aide de pandas .

  • Noms des pays où l’on paye en euros

    On sélectionne la bonne valeur de Currency_Code  ainsi :

    Ensuite, on ne garde que les noms des pays ainsi obtenus, pour obtenir :

 

Activité
Pour éviter les répétitions, utiliser la méthode  .unique()  qui s’applique à une série et non une trame de données.
  • Écrire l’instruction permettant de lister les codes de toutes les monnaies qui s’appellent ‘Dollar’.
  • Écrire l’instruction permettant de lister les noms des pays de plus de 100 millions d’habitants, sous la forme (Pays, Population).

 

Tris

Les méthodes .nlargerst()  et .nsmallest()  permettent de déterminer les plus grands et plus petits éléments selon un critère donné.

Ainsi, pour obtenir les 10 pays les plus grands en superficie et les 5 moins peuplés, on peut écrire :

 

Le tri d’une une trame de données s’effectue à l’aide de la méthode .sort_values() , comme par exemple :

 

Activité
  • Écrire les instructions permettant d’afficher les 10 pays les moins peuplés, sous la forme (pays, population).

 

On peut trier selon plusieurs critères, en spécifiant éventuellement les monotonies.

Ainsi, pour classer par continent puis par superficie décroissante (avec une sélection pertinente de champs) :

 

Manipulation de données

Création d’un nouveau champ

Il est très facile de créer de nouveaux champs à partir d’anciens.

Par exemple, pour calculer la densité de chaque pays, il suffit d’exécuter :

 

Tracés de graphiques

La bibliothèque pandas  permet également de réaliser toutes sortes de graphiques en exploitant les bibliothèques numpy et matplotlib  :

 

Les séries peuvent faire l’objet de graphiques.

Par exemple, on peut réaliser une carte des villes utilisant la projection de Mercator en effectuant :

 

Fusion de tables

Dans la table des pays, la capitale est indiquée par un numéro (champ Capital_Id )  … qui correspond au champ Id  de la table des villes. Pour récupérer le nom de la capitale de chaque pays, nous allons fusionner les tables en effectuant une jointure. Ainsi, nous allons faire correspondre le champ Capital_Id de pays  et le champ Id de villes .

Cela se fait à l’aide de la méthode .merge()  :

Cependant, en procédant ainsi, il va y avoir un conflit entre les champs des deux tables. Cela apparaît en listant les champs de la table obtenue :

On voit que des tables initiales contiennent toutes les deux des champs Name et Population : l’opération de fusion rajoute donc automatiquement les suffixes _x  et _y  pour marquer la référence à la première table initiale ou à la seconde.

Pour rendre cela plus lisible, nous allons :

  • ne garder que les colonnes de villes qui nous intéressent, ici l’identifiant et le nom ;
  • renommer ces colonnes pour éviter les collisions avec les champs de pays :

 

Et c’est cette nouvelle table que nous allons fusionner avec la table pays  (dont nous ne garderons pas toutes les colonnes non plus) :

La liste des pays d’Océanie et leurs capitales s’obtient alors facilement :

 

Conclusion

La bibliothèque pandas est un outil intéressant pour s’initier à la manipulation de données. En particulier, le rôle central qu’y jouent les trames de données permet de manipuler les enregistrements quasiment comme s’il s’agissait de p-uplets nommés.

Cependant, pour gérer des données organisées de façon plus complexe, notament lorsqu’il y a plusieurs tables en relationRelation Sous‐ensemble du produit cartésien de n domaines. On peut la représenter sous forme de table dans laquelle n attributs correspondent aux titres des n colonnes., de très nombreux enregistrements, … il faudra utiliser un système de gestion de bases de données (SGDB).

Ces derniers possèdent en plus de très nombreux avantages, comme l’accès aux données par plusieurs utilisateurs en même temps par exemple.

Vous aimerez aussi...

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *

*

code