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

La commande sorted permet de ranger des listes mais aussi des dictionnaires. L'instruction sort ne s'applique qu'aux listes et est une méthode, elle transforme la liste directement. La fonction sorted renvoie la liste triée mais ne modifie pas la liste d'origine! Voici des exemples sur des listes
>>> 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']
Voici un exemple sur des dictionnaires :
>>>dico={1:'tel fixe',2:'tel mobile'}
>>>print(sorted(dico))
[1, 2] #par défaut le dictionnaire est trié sur la clé
Voici un exemple sur des tuples :
>>>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

  1. Prenez un tableau csv de votre choix et appliquez les tris tels que proposés dans le cours.
  2. 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.

  3. 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.

  4. 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.

Android

De la programmation pour pc à la programmation pour téléphone.

A finir

Pas eu le temps de tout faire.....