Tri dans une table
Traitement des données en tables
Plan
Trier une table
Trier une table consiste à classer le tableau en fonction des valeurs d'une ou plusieurs colonnes. Deux solutions
- On récuppère le fichier csv dans une liste de liste ou dans une liste de dictionnaire et on programme nous même le tri dans une fonction. C'est un excellent exercice que nous ferons.
- On utilise une commande directement capable de faire ce tri. Encore une fois nous utiliserons la bibliothèque pandas
La commande sorted
>>> liste=[3,5,6] >>> liste2=sorted(liste) >>> print(liste) #liste n'est pas modifiée ! [3, 5, 6] >>> print(liste2) [3, 5, 6] >>> liste2.sort() >>> print(liste2) [3, 5, 6] >>>liste=[15,3,14,10] >>>print(sorted(liste)) [3,10,14,15] >>>liste=["ordinateur","alphabet"] >>>print(sorted(liste)) ["alphabet","ordinateur"] >>>print(sorted("Voici une chanson de Toto".split(), key=str.lower)) ['chanson','de','Toto','une','voici']
>>>dico={1:'tel fixe',2:'tel mobile'} >>>print(sorted(dico)) [1, 2] #par défaut le dictionnaire est trié sur la clé
>>>monTuple=[ ('johan','1998-02-17',175), ('nathan','1990-01-11',180)] >>>print(sorted(monTuple,key=lambda date: date[1])) [('nathan', '1990-01-11', 180), ('johan', '1998-02-17', 175)] >>>print(sorted(monTuple,key=lambda taille: taille[2])) [('johan', '1998-02-17', 175), ('nathan', '1990-01-11', 180)]
Pour effectuer le tri suivant une colonne autre que la première, j'ai utilisé une fonction lamda qui permet de définir le rang du champs pour le tri. A noter que les mots 'date' et 'taille' peuvent être remplacés par n'importe quelle chaine de caractère!
Notez l'astuce pour la date, ce format annee-mois-jour permet de trier facilement des dates comme une chaine de caractères ! On peut inverser l'ordre du tri en ajoutant en paramètre reverse=True.
On peut éviter l'utilisation de la commande lambda, qui n'est pas très claire pour le moment, en utilisant la méthode itemgetter mais attention il faut alors importer la bibliothèque opérator.
>>>print(sorted(monTuple, key=itemgetter(1),reverse=True))
La commande sorted sur un fichier CSV
On peut aussi trier un fichier CSV. Ce n'est pas très compliqué, il suffit de faire appel à la commande sorted! Ci dessous, on ouvre le fichier, on le lit puis on range les données selon la colonne 2. Ensuite, on écrit le résultat dans un autre fichier. L'exemple ci-dessous n'utilise pas pandas.
#avec les readers... #Avec cette méthode il ne faut pas de ligne d'entête #s'il y en a une elle va faire partie du tri #il faut donc la supprimer with open('ClasseurMetalPointVirgule.csv',newline='') as fichier_source: lecteur=csv.reader(fichier_source,delimiter=';',quotechar='|') print("next",lecteur.__next__()) # on fait le tri lignes_ordonnees = sorted(lecteur, key=lambda test: test[2]) with open('ClasseurMetalPointVirguleTrie.csv', 'w', newline='') as fichier_sortie: ecriteur = csv.writer(fichier_sortie, delimiter=';', quotechar='|', quoting=csv.QUOTE_MINIMAL) # on ecrit les lignes triées dans le nouveau fichier for ligne in lignes_ordonnees: ecriteur.writerow(ligne) #d'après le retour d'indentation, #on vient de fermer le fichier en écriture ! # on affiche le résultat for line in lignes_ordonnees: print(line) #avec les listes de dictionnaires #lecture et tri with open('ClasseurMetalPointVirgule.csv',newline='') as fichier_csv: lecteur = csv.DictReader(fichier_csv, delimiter=";") liste_rangee = sorted(lecteur, key=lambda row:(row['groupe'],row['Album']), reverse=False) #enregistrement with open('sorted.csv', 'w',newline='') as fichier_sortie: champs = ['Album', 'groupe', 'année','classement'] ecriteur = csv.DictWriter(fichier_sortie, fieldnames=champs,delimiter=';',quotechar='|') ecriteur.writeheader() for ligne in liste_rangee: ecriteur.writerow(ligne)
Voici la même chose mais avec pandas.
mon_classeur=pandas.read_csv('ClasseurMetalPointVirgule.csv',sep=";",encoding="latin") print(mon_classeur) tri_sur_groupe=mon_classeur.sort_values(by="groupe") print(tri_sur_groupe) tri_sur_album=mon_classeur.sort_values(by=["groupe","année"],ascending=False) print(tri_sur_album) tri_sur_groupe.to_csv("tri_sur_groupe.csv",sep=';',encoding='latin', index=False)
Exercices
- Prenez un tableau csv de votre choix et appliquez les tris tels que proposés dans le cours.
-
Adaptez un des programme de tri vu dans le chapitre des tris, pour qu'il puisse trier une liste de listes (bref une matrice), selon une colonne donnée. Par exemple tri_matrice(matrice,2), rangera les lignes en fonction des valeurs de la colonne 2.
-
A l'aide de l'exercice 1. En utilisant le code de lecture d'un fichier mis en liste de liste (code avec reader), trier un fichier csv suivant une colonne donnée puis enregistrez le fichier.
-
En utilisant la bibliothèque pandas(installez anaconda sur votre pc si necessaire, puis pip install pandas !):
a) ouvrir le fichier mars-2014-complete et faire afficher le nombre de lignes. telecharger
b) effacer les doublons sur les 4 premiers champs, faire afficher le nombre de lignes, et enregistrer dans un fichier mars-propre
c) Avec Mars-propre, selectionner les colonnes lib-mrq, lib_mod_doss_, puiss_max,conso_urb, hcnox,ptcl, et enregistrer cela dans un nouveau fichier mars-selection. L'ouvrir avec excel pour vérifier.
d) ouvrir le fichier mars-selection et le trier suivant le champ hcnox pour trouver la voiture qui pollue le plus et celle qui pollue le moins. Pour supprimer les lignes qui contiennent nan vous pouvez utiliser la méthode .notna() sur le champs.
e) ouvrir le fichier précédent et ne faire afficher que les voitures dont la marque commence par la lettre de votre prénom (ou de votre nom si n'existe pas avec votre prénom) et la puissance est inférieure à 150 cv. Sauver dans ma-selection. Pour selectionner 'commencent par', on utilise la méthode .str.startwith('M') sur le champs de selection.