Skip to content

NSI - Terminale - Traitement des données en table

Le cours

Cliquez sur le lien du chapitre de cours à consulter:

le fichier csv

  • tableaux de données (tables)

Il est fréquent en informatique d'organiser des données sous la forme d'un tableau que l'on stocke ensuite dans un fichier selon un format de structuration ( csv, json, xml, … ). Lors du traitement de ces informations, les données sont "importées" depuis le fichier dans un objet de types construits comme une liste de dictionnaires ou une liste de listes.

  • Le format de stucturation csv

Par exemple, on cherche à représenter les élèves d'une classe. Dans un fichier csv les données seront organisées sous la forme d'un texte codé en utf-8 qui contiendra:

En première ligne des descripteurs, on appelle descripteurs la nature des données stockées, par exemple pour un élève les descripteurs pourraient être son prénom, son nom, sa date de naissance et sa classe. Sur la première ligne, chaque descripteur est séparé par un caractère de séparation ( un point virgule ";" ou une virgule "," ou deux points verticaux ":")

Les autres lignes du fichier seront les enregistrements organisés avec un enregistrement par ligne ( un élève par ligne) , chaque donnée inscrite correspond à la valeur du descripteur pour cet élève et elle est séparée des autres données par le caractère de séparation choisi, exemple:

prénom; nom; date_de_naissance; classe
Abel; Auboisdormant; 01/05/2010; 210
Yann; Amarre; 12/10/2010; 210

Indexation des données sous forme de liste de dictionnaires

Lors du traitement en python, on peut importer les données du fichier dans un objet liste qui contiendra des dictionnaires. Chaque dictionnaire représentera un enregistrement ( un élève) du fichier csv. Les clés du dictionnaire sont les descripteurs et les valeurs sont les données de l'enregistrement:

[ {'prénom':'Abel', 'nom':'Auboisdormant', 'date_de_naissance':'01/05/2010', 'classe':'210'},

{'prénom':'Yann', 'nom':'Amarre', 'date_de_naissance':'12/10/2010', 'classe':'210'} ]

Le module csv de python contient des fonctions que l'on va utiliser pour l'importation des données et leur manipulation.

import csv 
'''on ouvre le fichier en mémoire et
on l'assigne à la variable fichier'''
fichier = open("classe_1G8.csv", encoding='utf-8')
''' création d'une liste avec l'objet renvoyé par la fonction DictReader 
que l'on assigne à la variable table '''
table = list(csv.DictReader(fichier, delimiter=";")) 
print(table)
# après utilisation, on referme le fichier 
fichier.close()
Autre façon de coder:

import csv
'''on ouvre le fichier en mémoire et
on l'assigne à la variable fichier'''
with open("classe_1G8.csv", encoding='utf-8') as fichier:
  # création de la liste de dictionnaires assignée à table
  table = list(csv.DictReader(fichier,delimiter=";"))
  # affichage de la liste des dictionnaires
  print(table)
  # après utilisation, on referme le fichier
  fichier.close()
L'affichage sera:

pb affichage

Selon les versions de python vous pouvez obtenir une liste d'OrderedDict ( un OrderedDict malgré son apparence complexe est un objet qui se manipule comme un dictionnaire).

[ OrderedDict([('Prénom', 'Sophie'), (' Nom', ' Fonfec'), (' date_de_naissance', ' 01-01-04'), (' classe ', '1G8')]) , OrderedDict([('Prénom', ‘Nordine'), (' Nom', ' Ozor'), (' date_de_naissance', ' 24-06-04'), (' classe ', '1G8')]) , OrderedDict([('Prénom', 'Théo'), (' Nom', ' Top'), (' date_de_naissance', ' 14-02-04'), (' classe ', ' 1G8')]), OrderedDict([('Prénom', 'Yann'), (' Nom', ' Amare'), (' date_de_naissance', ' 05-06-04'), (' classe ', '1G8')]), OrderedDict([('Prénom', 'Adémar'), (' Nom', ' Aucardetour'), (' date_de_naissance', ' 12-12-04'), (' classe ', ' 1G8')]), OrderedDict([('Prénom', 'Paul'), (' Nom', ' Auchon'), (' date_de_naissance', ' 04-05-04'), (' classe ', ' 1G8')])]

Recherche d'un élément dans une table

Rappel: le mot table est une franglaiserie, table est le mot Anglais pour tableau, c'est donc un objet list en python.

Ecrivons une fonction presence_eleve (liste, nom) qui prend deux arguments : la variable liste associée à une liste de dictionnaires et la variable nom associée à une chaine de caractères qui représente un nom d'élève.
On cherche à savoir si un élève qui porte ce nom est bien présent dans la liste.

La fonction renverra le booléen True si l'élève est présent et False dans le cas contraire:

#***********************************************#
#              DEFINITIONS                      #
#***********************************************#
import csv
# définition de la fonction de recherche
def presence_eleve ( liste, nom) :
# chaque dictionnaire de liste
for dico in liste:
    # si la valeur associée à la clé nom du dictionnaire 
    # est égale à la valeur de la variable nom
    if dico['Nom'] == nom:
        # quitte la fonction et revoie True
        return True
# après parcours de tous les dicos
# quitte la fonction et revoie False
return False


#***********************************************#
#              UTILISATION                      #
#***********************************************#

# importation des données du fichier csv
'''ouvrir le fichier en mémoire et
l'assigner à la variable fichier'''
fichier = open("classe_1G8.csv", encoding='utf-8')
''' créer une liste avec l'objet renvoyé par la fonction DictReader 
et l'assigner à la variable table '''
table = list(csv.DictReader(fichier, delimiter=";")) 
print(table)
# après utilisation, refermer le fichier 
fichier.close()

# rechercher 'Fonfec' dans la table ( utilisation de la fonction)
le_nom = 'Fonfec' 
print( f"l'élève {le_nom} est-elle présente ?", presence_eleve (table, le_nom))

Conversion des données

On peut être amené lors du traitement à convertir les données pour pouvoir effectuer des calculs parce que les données brutes extraites du fichier csv sont des caractères utf-8:

Soit le fichier csv suivant:
pb affichage

Voici un code qui importe les données et les converties:

# liste pour données converties
table = []
# on ouvre le fichier csv en mémoire
with open(fichier_csv, mode='r', encoding='utf-8') as fichier:
    # on importe les données avec DictReader 
    lecteur_csv = csv.(fichier, delimiter=",")
    # pour chaque dictionnaire de la collection
    for dico in lecteur_csv:
        # strip() enlève les espaces '269.87 ' deviendrait '269.87'
        montant = dico['montant'].strip()
        mois = dico['mois'].strip()
        # avant conversion les "," sont remplacées par des "."
        # avec replace(",", "."): '269,87' devient '269.87'
        # on convertit les données montant et mois en nombre
        # et on les réaffecte comme valeur aux clés du dictionnaire
        dico['montant'] = float(montant.replace(",", "."))
        dico['mois'] = int(dico['mois'])
        # on ajoute le dictionnaire convertit dans notre liste
        table.append(dico)
# on affiche notre liste table
print(table)
# on referme le fichier
L'affichage:

pb affichage

Explication:
lecteur_csv est une variable assignée à un objet itérable ( une collection de dictionnaires ) renvoyé par DictReader; on parcourt la collection de dictionnaires avec le code "for dico in lecteur_csv" pour chaque dictionnaire on convertit la valeur de sa clé 'montant' et celle de sa clé 'mois' en nombre , enfin on ajoute le dictionnaire modifié à la liste table.

Indexation sous forme de liste

On peut aussi importer les données du fichier csv sous la forme d'une liste de listes. On utilise alors la fonction reader du module csv au lieu de la fonction DictReader.

import csv 
# on ouvre le fichier en mémoire et
# on l'assigne à la variable fichier
fichier = open("classe_1G8.csv", encoding='utf-8')
# création d'une liste avec l'objet renvoyé par reader 
table = list(csv.reader(fichier, delimiter=";"))
# affichage de la liste
print(table)
# après utilisation, on referme le fichier 
fichier.close()
L'affichage:

pb affichage

Tris des données en table

On peut être amené à trier les données importées. La fonction sorted(liste, ..) permet d'obtenir la copie d'une liste que l'on peut trier sans affecter la liste originale.

La fonction sorted(liste, ..) renvoie une copie de la liste passée en argument selon un critère de tri à préciser.

Reprenons la liste de dictionnaires de la 1G8:

pb affichage

Comment classer les dictionnaires selon l'ordre alphabétique des noms dans chaque dictionnaire ?

La fonction sorted possède deux arguments optionnels key et reverse.

L'argument key permet de préciser un critére de tri, cet argument doit se voir affecter une fonction de callback, une fonction de callback est une fonction passée en argument d'une autre fonction ici à sorted.

Voici comment utiliser key :

pb affichage

Résultat:

pb affichage

Si la fonction f ne sert qu'à ça, il est inutile d'utiliser une fonction nommée, on utilise plutôt une fonction lambda, une fonction lambda est une fonction qui n'a pas de nom ( fonction anonyme) elle est souvent utilisée comme fonction de callback.

pb affichage

Le code devient:

import csv
# on ouvre le fichier en mémoire et
# on l'assigne à la variable fichier
with open("classe_1G8.csv", encoding='utf-8') as fichier:
    # création de la liste de dictionnaires
    table = list(csv.DictReader(fichier,delimiter=";"))
    print(" Avant tri:")
    print(table)
    # après utilisation, on referme le fichier
    fichier.close()
    # tri de table
    table = sorted(table, key=lambda dico:dico['Nom'])
    print(" Après tri:")
    print(table)
Remarques: on ne voit pas bien comment la fonction sorted utilise key, il faut accepter l'abstraction et juste comprendre comment procéder pour associer dico['Nom'] à key

L'argument reverse permet d'inverser l'ordre; au lieu d'un tri dans l'ordre croissant (de a à z ), si reverse = True, le tri devient l'ordre décroissant (de z à a) :

import csv
# on ouvre le fichier en mémoire et
# on l'assigne à la variable fichier
with open("classe_1G8.csv", encoding='utf-8') as fichier:
    # création de la liste de dictionnaires
    table = list(csv.DictReader(fichier,delimiter=";"))
    print(" Avant le tri:")
    print(table)
    # après utilisation, on referme le fichier
    fichier.close()
    # tri de table ordre décroissant 
    table = sorted(table, key=lambda dico:dico['Nom'], reverse = True )
    print(" Après le tri:")
    print(table)

Création d'un fichier csv à partir d'une table

Voici un code python qui crée un fichier csv à partir d'une liste de dictionnaires:

# création d’un fichier csv en mode écriture (w)
fichier_csv = open("new_classe_1G8.csv",'w')
# création de la liste des champs par lecture des clés du premier dico
# liste_champ vaut ['Prénom', 'Nom', 'date_de_naissance', 'classe ']
liste_champ = list(table[0].keys())
# création d’une chaine vide
chaine = ""  
# parcours des éléments de la liste et ajout dans la chaine
for element in liste_champ:
    chaine = chaine + element + ";"
# chaine vaut "Prénom;Nom;date_de_naissance;classe;"     
# retrait du dernier point virgule « ; »
chaine = chaine[0:len(chaine)-1]
# chaine vaut "Prénom;Nom;date_de_naissance;classe"   
# écriture de la chaine dans le fichier csv + caractère fin de ligne
fichier_csv.write(chaine + "\n")
# fermeture du fichier
fichier_csv.close()
# réouverture en mode ajout ( « a » pour append ) 
fichier_csv = open("new_classe_1G8.csv",'a')
# pour chaque dico de la table
for dicos in table:
    # on crée une liste des valeurs
    # premier dico: liste_valeurs vaudra ['Sophie','Fonfec','01-01-04', '1G8']  
    liste_valeurs = list(dicos.values())
    chaine ="" 
    # on ajoute les valeurs dans la chaine
    for valeur in liste_valeurs:
        chaine = chaine + valeur + ";"      
    # on retire le dernier ; 
    chaine = chaine[0:len(chaine)-1]
    # on écrit la chaine dans le fichier avec caractère de fin de ligne
    fichier_csv.write(chaine + "\n")
# après l’écriture on referme le fichier csv
fichier_csv.close()