Données en table (format csv) : filtres, tris
Données en exemple pour le TP
On va utiliser les fichiers villes.csv et pays.csv.
Lire le format csv en python
import csv
fichier = open("pays.csv")
pays = list(csv.DictReader(fichier,delimiter=";"))
Ensuite on peut tester dans la console:
>>> pays[0]
{'ISO': 'AD', 'Name': 'Andorra', 'Capital_Id': '3041563', 'Area': '468', 'Population': '84000', 'Continent': 'EU', 'Currency_Code': 'EUR', 'Currency_Name': 'Euro'}
À faire
Ouvrez Thonny et enregistrer le fichier python au même endroit que les fichiers csv.
Copiez et exécuter les lignes au dessus :
- quel est le type de
pays
? - quel est le type de
pays[0]
? C'est un type très proche dedict
qu'on pourra utiliser comme si c'était un dictionnaire
Chaque p-uplet de données est donc représenté par un dictionnaire en python, où les clés sont les noms des descripteurs qui sont les mêmes pour chaque p-uplet, et les valeurs associées sont celles de la ligne de la table correspondante.
Attention
Le type des valeurs en python si on lit le fichier comme ça sera toujours string
. Si la valeur est en fait un nombre et qu'on veut faire des calculs ou des comparaisons dessus, il faudra la convertir avec int()
ou float()
.
Pour parcourir toute la table, on peut faire une boucle for qui parcourt directement la liste des dictionnaires :
for p in pays:
print(p)
On va maintenant pouvoir modifier cette boucle pour répondre à diverses questions sur les données.
Filtrer la table
En rajoutant un test if
dans la boucle, on peut afficher seulement les lignes
qui vérifient une proposition logique.
À faire
-
Combien de pays ont pour monnaie le dinar ? Il s'agit de n'afficher que les lignes où la valeur du descripteur
"Currency_Name"
vaut"Dinar"
. -
Quels sont les pays d'Amérique du Sud dont la monnaie s'appelle "Dollar" ? Il faut faire la conjonction de deux conditions dans le if avec
and
. Le code du continent pour l'amérique du sud est "SA". -
Quels sont les pays qui ont moins de 1000 habitants ? Attention, il faut convertir la valeur de Population en int pour pouvoir la comparer.
Aggrégation de résultats
De la même manière que quand on cherchait le minimum ou la somme des éléments d'un tableau, on peut créer une variable avant la boucle et la mettre à jour pour calculer quelque chose sur la table.
À faire
-
Quelle est la population mondiale totale d'après ces données ? (encore une fois, convertir la Population des pays en int pour les additionner)
-
Quel est le pays qui a le plus petit nombre d'habitants au km² ? Et de combien est cette densité ?
Trier la table
Comme dans un tableur, on peut vouloir trier la table dans un certain ordre.
En python on peut trier une liste de manière efficace avec la méthode .sort()
,
mais nos données sont dans une liste de dictionnaire et les dictionnaires ne sont
pas directement comparables donc on obtient une erreur :
>>> pays.sort()
Traceback (most recent call last):
File "<pyshell>", line 1, in <module>
TypeError: '<' not supported between instances of 'dict' and 'dict'
Pour résoudre ce problème, on peut ajouter un paramètre nommé key
à la méthode
sort
qui doit être une fonction qui va convertir les éléments du dictionnaire en
quelque chose de comparable.
Par exemple on peut créer une fonction population
qui transforme un p-uplet en
la valeur de sa population de type int
, ce qui permet de trier par population croissante.
def population(p):
return int(p["Population"])
pays.sort(key=population)
À Faire
- Quel est le 10e plus grand pays au monde ? (Indice : pour trier par ordre décroissant, on peut donner comme key une fonction qui renvoie l'opposé de la valeur)
Si on veut trier par plusieurs critères (par exemple par ordre alphabétique de monnaie, et si la monnaie est égale par ordre alphabétique du nom de pays) on peut renvoyer un tuple :
def monnaie_puis_nom(p):
return (p["Currency_Name"],p["Name"])
pays.sort(key=monnaie_puis_nom)
À faire
-
Quel est le premier pays qu'on obtient si on trie d'abord par la longueur du nom du pays, et à longueur égale par population croissante ?
-
(tri + filtre) Quel est le 4e plus grand pays de la zone euro ?
Sauvegarder une nouvelle table dans un fichier csv
On peut utiliser DictWriter
pour écrire un nouveau fichier csv.
Par exemple, pour écrire un fichier csv des pays de la zone euro :
pays_euro = []
for p in pays:
if p["Currency_Name"]=="Euro":
pays_euro.append(p)
fichier_out = open("euro.csv","w") # "w" pour l'ouverture en écriture (write)
noms_descripteurs = pays_euro[0].keys() # .keys() donne les clés d'un dictionnaire, donc les descripteurs ici
writer = csv.DictWriter(fichier_out,noms_descripteurs)
writer.writeheader() # écrire les noms des descripteurs
writer.writerows(pays_euro) # écrire toutes les lignes de la liste pays_euro
fichier_out.close() # fermer le fichier
À faire
- Créez un fichier csv qui liste les pays du continent asiatique.
Fusion de tables
On n'a pas encore utilisé le fichier ̀villes.csv`, qui recense des données sur 24338 villes dans le monde.
La colonne Country_ISO
correspond à la colonne ISO du fichier pays.csv, et la
colonne Capital_Id
de pays.csv correspond à la colonne Id
de villes.csv.
On veut parfois faire des requêtes sur plusieurs tables à la fois, par exemple :
- Quelles sont les 3 villes au monde avec plus de 12 millions d'habitants qui ne sont pas des capitales ?
Pour y répondre, on ne sait pas dans la table villes.csv
si une ville est une capitale. Il faut donc:
Pour chaque ville:
Si elle a plus de 12 millions d'habitants:
est_capitale = False
Pour chaque pays:
Si la capitale du pays est la ville actuelle:
est_capitale = True
Si est_capitale est True:
afficher la ville
Info
Ces opérations sur les tables (en particulier les jointures) seront plus faciles et efficaces à réaliser si on les stocke sous forme de base de données. Le langage SQL sert alors à écrire des requêtes qui sont exécutées par un logiciel spécialisé : un système de gestion de base de données (SGBD).
Tout cela est au programme de NSI de Terminale.
Questions supplémentaires
-
Quelle est la ville d'Inde la plus au sud ?
-
Quelle est la ville de la liste qui a le nombre d'habitants le plus proche de Grenoble ?
-
Pour chaque continent, quelle est la ville qui a le nombre d'habitants le plus proche de Grenoble ?
-
Quelle est la ville la plus proche du point de la Terre opposé à Grenoble ?
-
(Pour occuper si vous avez trop de temps :) On veut aller à Shanghai à vélo en s'arrêtant chaque soir dans une ville. Avec quelle longueur d'étape maximale en km peut-on y arriver ?