Page 10 bis

Manipulation de fichiers CSV (pour les sciences physiques ?)

On a vu dans la page 10 que Python permet d'extraire des données entières contenues dans un fichier CSV ou dans un fichier tableur (Excel / Libre Office) à l'aide du module CSV de Python.
Dans ce qui suit, on se propose d'étudier le cas où ces données sont décimales ce qui est souvent le cas en sciences physiques.
Trois versions sont proposées.

  1. Version 1 : Cette version utilise les modules numpy et mathplotlib pour traiter un fichier csv dont le sérarateur décimal est le point.
  2. Version 2 : Cette version utilise les modules numpy et mathplotlib pour traiter un fichier txt dont le sérarateur décimal est le point.
  3. Version 3 : Cette version utilise uniquement le module csv. Le code est beaucoup plus complexe mais ne demande pas de travail sur le fichier csv avant son traitement par Python.

Avant toutes choses commençons par créer un fichier csv avec des données en colonnes.

Création d'un fichier

Commençons par remplir un fichier tableur, en colonne, comme on pourrait le faire lors d'un TP de sciences physique par exemple. Pour cela, on utilisera Libre Office Calc mais on pourrait faire la même chose avec Excel. On enregistrera ce fichier une première fois sous le nom FichierDonneesCononne.odt et on gardera soigneusement ce fichier car il nous resservira dans la version 2.

  1. Ouvrir un fichier Libre Office Calc.
  2. Saisir le tableau suivant dans les deux premières colonnes (en commençant par la première ligne).
    FenetreTableur
  3. Créer un dossier que vous nommerez FichierCSV_Version1 puis à l'aide de Fichier/Enregistrer sous, enregistrez ce fichier avec le nom FichierDonneesLigne et avec l'extension .csv (Voir ci-dessous).
    FenetreTableur
  4. Quand la fenêtre ci-dessous s'ouvre, cliquez sur « utiliser le format CSV ».
    FenetreTableur
  5. La fenêtre suivante apparaît. Avant de cliquer sur OK, réglez les champs comme ci-dessous. Le séparateur de champ est un point virgule.
    FenetreTableur
  6. Fermez le fichier FichierDonneesLigne.csv
  7. Pour voir ce que ce fichier contient, ouvrez le en faisant un clique droit puis « ouvrir avec » puis « libre Office Calc ».
    La fenêtre qui s'ouvre doit être réglée comme ci-dessous. Cliquez ensuite sur OK.
    FenetreTableur
  8. Le fichier s'ouvre et il est sous la forme suivante.
    FenetreTableur
  9. Nous allons maintenant traiter ce fichier avec Python.

Problème : On remarque que dans ce fichier le séparateur décimal est la virgule alors que Python utilise le point.

Version 1

Le code présenté dans cette version utilise les modules numpy et mathplotlib. Il permet d'extraire les données, contenues dans un fichier csv et présentées en colonne, puis il permet de les traiter. Ici, on ne fait que tracer le nuage de points correspondant mais on pourrait faire bien d'autres choses : tracer la droite de regression, calculer les moyennes ...
L'avantage de ce code c'est qu'il est synthétique. L'inconvénient c'est qu'il nécessite de transformer le fichier csv en amont, de manière à ce que le séparateur décimal devienne le point et non la virgule.

Pour transformer les virgules en points dans le fichier FichierDonneesLigne.csv, il suffit de l'ouvrir en double-cliquant dessus, de répondre OK à la fenêtre qui s'ouvre puis de faire un CTRL + H et de remplacer toutes les virgules par des points. On ferme ensuite les fenêtres qui s'ouvrent puis on enregistre le fichier en vérifiant qu'il garde bien l'extension .csv.

Copiez le code suivant dans l'éditeur d'EduPython. Enregistrez le fichier Python dans le dossier FichierCSV_Version1 en lui donnant, par exemple, le nom FichierCSV_V1.py.
Ainsi dans le dossier FichierCSV_Version1, on doit trouver les fichiers FichierDonneesLigne.csv et FichierCSV_V1.py.
Analysez ce code puis lancez le programme en observant la console et la fenêtre obtenue.


# -*- coding: utf-8 -*-

#Importation de données d'un fichier CSV (Version 1)

#importation du module numpy afin de lire le contenu du fichier csv et simplification en np
import numpy as np

#importation du module matplotlib.pyplot pour construire le graphique et et simplification en plt
import matplotlib.pyplot as plt

#Recherche des coordonnéees des points dans le fichier panenka.csv
#les données sont séparées par des ";" à  partir de la 3 ème ligne (notée 2)
pointage = np.loadtxt("FichierDonneesColonne.csv",delimiter=';',skiprows=1)

#lecture des abscisses x issues de la première colonne (notée 0) du fichier csv
#les données se retrouveront dans un tableau d'une ligne
x=pointage[:,0]

#lecture des ordonnées y issues de la deuxième colonne (notée 1) du fichier csv
#les données se retrouveront dans un tableau d'une ligne
y=pointage[:,1]

print(type(y))
print("Abscisses x en m :",x)
print("Ordonnées y en m :",y)

#affiche le nuage de points de taille 50, de couleur rouge et sous forme de croix"
plt.scatter(x,y,s=50,c = 'red',marker= '+')

#affiche un repère othonormal
#plt.axis('equal')
plt.axis([0,0.8,0,0.8])

plt.title("Affichage de données à partir d'un fichier CSV (version 1)")  # Affiche le titre
plt.xlabel('abcisse x')           # Affiche un commentaire sur l'axe des abscisses
plt.ylabel('ordonnée y')         # Affiche un commentaire sur l'axe des ordonnées
plt. plot (x,y,'g')               # Trace une liaison entre les points en bleu
plt.show()                        # Montre le graphique à l'écran

Version 2

Le code présenté dans cette version utilise encore les modules numpy et mathplotlib mais cette fois il permet d'extraire les données, contenues dans un fichier txt (et présentées en colonne).
Comme pour la version 1, l'avantage de ce code c'est qu'il est synthétique. Son inconvénient c'est qu'il nécessite la transformation des virgules en points.

On crée un nouveau dossier que l'on appelle FichierCSV_Version2. On ouvre le fichier FichierDonneesColonne.odt que l'on avait créé au tout début. On saisit la plage de données et on la copie dans le Bloc-Note. On enregistre ce fichier dans le dossier FichierCSV_Version2 en lui donnant le nom FichierDonneesColonne.txt.
On obtient ce qui suit. Les deux colonnes sont séparées par une tabulation.
FenetreTableur
Pour transformer les virgules en points dans ce fichier FichierDonneesLigne.txt, il suffit à nouveau de faire un CTRL + H et de remplacer toutes les virgules par des points. On ferme ensuite les fenêtres qui s'ouvrent puis on enregistre le fichier en vérifiant qu'il garde bien l'extension .txt.

FenetreTableur

Copiez le code suivant dans l'éditeur d'EduPython. Enregistrez le fichier Python dans le dossier FichierCSV_Version2 en lui donnant, par exemple, le nom FichierCSV_V2.py.
Ainsi dans le dossier FichierCSV_Version2, on doit trouver les fichiers FichierDonneesLigne.txt et FichierCSV_V2.py.
Analysez ce code puis lancez le programme en observant la console et la fenêtre obtenue.


# -*- coding: utf-8 -*-

from numpy import*
from matplotlib.pyplot import*

x,y = genfromtxt("essai.txt" , skip_header = 2 , unpack=True)
print(x)
print(y)
scatter(x,y,s=50,c='r',marker='+') #On trace les points
axis([0,0.8,0,0.8])
title('Trajectoire')
xlabel('x en m')
ylabel('y en m')
plot(x,y,'g')      #on relie ces points
show()

Version 3

Dans cette dernière version on utilise le module csv et il n'y a pas de traitement du fichier de données en amont. Par contre, le code est beaucoup plus complexe même si, dans ce qui suit, il a été décomposé en plusieurs étapes de manière à en faciliter la compréhension.

On crée un dossier FichierCSV_Version3 dans lequel on place un fichier FichierDonneesLigne.csv qui est le même tableau que dans les versions précédentes mais cette fois rempli en ligne. On l'obtient en faisant d'abord cette saisie dans Libre Office Calc
FenetreTableur
puis on créant le fichier FichierDonneesLigne.csv (voir le haut de la page).
Lorsqu'on ouvre ce fichier, on se souvient qu'il nous apparait sous cette forme
FenetreTableur
On remarque que le séparateur décimal est la virgule et que les données d'une même ligne sont séparées par un point-virgule.

Nous allons enregistrer les données décimales contenues dans le fichier CSV dans un tableau Python (une liste de listes) pour pouvoir les traiter.
On insiste lourdement. Ces données ont la virgule comme séparateur décimal et sont des chaines de caractères...pour l'instant !

On rappelle que pour plus de renseignements sur le la manipulation des fichiers csv, on peut ouvrir le lien ci-dessous.

https://docs.python.org/3/library/csv.html

Copiez le code suivant dans l'éditeur d'EduPython, puis enregistrez le dans le dossier FichierCSV_Version3 que vous avez créé. Lisez le attentivement. Les fonctions replace(...,...) et float(...) y sont utilisées.
Après avoir lancé le programme, les résultats obtenus dans la console permettront de comprendre comment ces fonctions sont utilisées.



# -*- coding: utf-8 -*-

#On rappelle que le tableau CSV est donné en ligne

#On importe le module CSV
import csv

with open('FichierDonneesLigne.csv',newline='') as f:    #Ouverture du fichier CSV
    #chargement des lignes du fichier csv
    lire=csv.reader(f,delimiter=';')
    for ligne in lire:                  #Pour chaque ligne...
        print(ligne, end='\n')          #...affichage de la ligne dans la console

#Comme on va le voir dans les lignes suivantes, on obtient les valeurs du tableau....
#... sous forme de string. La virgule est utilisée comme séparateur décimal ...
#... alors que Python utilise le point.

#Intéressons nous à la dernière ligne du tableau CSV contenue dans la variable ligne
print('Variable ligne :',ligne)
print('Cette variable ligne est une liste de string : ',type(ligne))

#Interessons nous à la troisième valeur de cette liste
print('Troisième valeur de la liste : ',ligne[2])
print('Type de cette troisième valeur : ',type(ligne[2]))

# Remplaçons la virgule par un point
ligne[2]=ligne[2].replace(',','.')
print('La virgule a été remplacée par un point : ',ligne[2])
print('Le type de la variable est toujours : ',type(ligne[2]))

#Enfin convertissons cette chaine de caractère en float
ligne[2]=float(ligne[2])
print('Le type de la variable est maintenant : ',type(ligne[2]))

		

Dans ce qui suit, on crée une fonction, nommée Transforme_Ligne(...), qui va transformer les colonnes du fichier CSV de manière à ce que les valeurs numériques saisies dans le tableur soient des variables de type float dans une liste Python nommée tableau.
Ainsi, il faut transformer les virgules en points à l'aide de replace(...,...) puis transformer la chaine de caractère obtenue en float à l'aide de float(...)
Comme précédemment, copiez le code suivant dans l'éditeur d'EduPython, puis enregistrez le dans le dossier FichierCSV_Version3. Lisez-le attentivement, lancez le programme puis observez ce que l'on obtient dans la console.


# -*- coding: utf-8 -*-

#Tableau donné en ligne
import csv

#On crée un tableau dans lequel on va mettre les valeurs contenues dans le CSV
tableau=[]

with open('FichierDonneesLigne.csv',newline='') as f:    #Ouverture du fichier CSV
    #chargement des lignes du fichier csv
    lire=csv.reader(f,delimiter=';')
    for ligne in lire:              #Pour chaque ligne...
        #print(ligne, end='\n')      #...affichage de la ligne dans la console
        tableau.append(ligne)        #...on ajoute la ligne dans la liste ...
                                     #...de liste nommée tableau

#On obtient une liste de listes
print('La variable tableau est égale à :\n',tableau)

#On crée une fonction qui va transformer les lignes du fichier CSV de manière ...
# ... à ce que les valeurs numériques saisies dans le tableur ...
# ...soient des variables de type float dans la liste Python

def Transforme_Ligne(lgn):
    n=len(lgn)   # la taille de la liste est n
    for i in range(1,n):
        # On doit donc remplacer la virgule par un point
        lgn[i]=lgn[i].replace(',','.')
        #Puis on convertit cette chaine de caractère en float
        lgn[i]=float(lgn[i])
    return lgn

#print("Première liste avant transformation : ",tableau[0])
#print("Première liste après transformation : ",Transforme_Ligne(tableau[0]))

#On remarque que pour obtenir la troisième valeur de la deuxième ligne ...
# ...du tableau CSV (en ne tenant pas compte de la première colonne),
print("Troisième valeur de la première ligne du fichier CSV : ",tableau[0][3])

#On transforme maintenant toutes les lignes de la variable tableau ...
#....de manière à ce que l'on puisse traiter les données.

m=len(tableau)
for i in range(m):
    tableau[i]=Transforme_Ligne(tableau[i])

print('Le tableau CSV est maintenant contenu dans la variable Python tableau : \n',tableau,'\n')

print('Le descripteur est de la ligne 0 est : ',tableau[0][0])
print('Les valeurs prises par ce descripteur sont : ',tableau[0][1:])

On est maintenant capable de récupérer n'importe quelles données d'un fichier CSV rempli en lignes.
En pratique on pourra utiliser le code suivant (moins didactique et plus synthètique).


# -*- coding: utf-8 -*-

#Extraction de données d'un fichier CSV. Ces données étant présentées en ligne
import csv  # On imorte le module csv

#On crée un tableau dans lequel on va mettre les lignes contenues dans le CSV
tableau0=[]

with open('FichierDonneesLigne.csv',newline='') as f: #Ouverture du fichier CSV
    #chargement des lignes du fichier csv
    lire=csv.reader(f,delimiter=';')
    for ligne in lire:              #Pour chaque ligne...
        #print(ligne, end='\n')      #...affichage de la ligne dans la console
        tableau0.append(ligne)        #...on ajoute la ligne dans la liste ...
                                     #...de liste nommée tableau

#On obtient une liste de listes
print('Initialement, la variable tableau est égale à :\n',tableau0)

#On crée une fonction qui va transformer les lignes du fichier CSV de manière...
# ... à ce que les valeurs numériques saisies dans le tableur...
# ...soient des variables de type float dans la liste Python

def Transforme_Ligne(lgn):
    n=len(lgn)   # la taille de la liste est n
    for i in range(1,n):
        # On doit donc remplacer la virgule par un point
        lgn[i]=lgn[i].replace(',','.')
        #Puis on convertit cette chaine de caractère en float
        lgn[i]=float(lgn[i])
    return lgn


#La fonction suivante transforme maintenant toutes les lignes de  ...
#...la variable tableau de manière à ce que l'on puisse traiter les données.
def Creation_Tableau(tab):
    m=len(tab)
    for i in range(m):
        tab[i]=Transforme_Ligne(tab[i])
    return tab

tableau1=Creation_Tableau(tableau0)

print('Après traitement, le tableau CSV est maintenant contenu')
print(' dans la variable Python tableau : \n',tableau1,'\n')


Dans le cas où les données auraient été remplies en colonnes, voici le code à utiliser.
Voici le fichier de données en colonne que vous téléchargerez en faisant clique-droit puis "enregistrer la cible du lien sous ..." sur le lien suivant : Télécharger ici


# -*- coding: utf-8 -*-

#Extraction de données d'un fichier CSV. Ces données étant présentées en colonnes
import csv  #on imorte le module csv

#On crée un tableau dans lequel on va mettre les valeurs contenues ...
# ... dans le CSV présenté en colonne
tableau0=[]

with open('FichierDonneesColonne.csv',newline='') as f:    #Ouverture du fichier CSV
    #chargement des lignes du fichier csv
    lire=csv.reader(f,delimiter=';')
    for ligne in lire:              #Pour chaque ligne...
        #print(ligne, end='\n')      #...affichage de la ligne dans la console
        tableau0.append(ligne)        #...on ajoute la ligne dans la liste ...
                                     #...de liste nommée tableau

#On obtient la liste des lignes du tableau
print('Initialement, la variable tableau est égale à :\n',tableau0)

#On crée une fonction qui permet d'obtenir les colonnes du tableau CSV

def Colonne_Ligne(tab):
    nb_ligne=len(tab)
    nb_col=len(tab[0])
    tab_lign=[]
    for i in range(nb_col):
        ligne=[]
        for j in range(nb_ligne):
            ligne.append(tab[j][i])
        tab_lign.append(ligne)
    return tab_lign

#On crée une fonction qui va transformer les colonnes du fichier CSV de manière ...
# ... à ce que les valeurs numériques saisies dans le tableur ...
# ...soient des variables de type float dans la liste Python

def Transforme_Ligne(lgn):
    n=len(lgn)   # la taille de la liste est n
    for i in range(1,n):
        # On doit donc remplacer la virgule par un point
        lgn[i]=lgn[i].replace(',','.')
        #Puis on convertit cette chaine de caractère en float
        lgn[i]=float(lgn[i])
    return lgn


#La fonction suivante transforme maintenant toutes les lignes de la variable tableau ...
#....de manière à ce que l'on puisse traiter les données.

def Creation_Tableau(tab):
    m=len(tab)
    for i in range(m):
        tab[i]=Transforme_Ligne(tab[i])
    return tab

#On met les colonnes du tableau CSV dans un tableau
tableau1=Colonne_Ligne(tableau0)
print('on met les colonnes du tableau initiale en ligne\n',tableau1)

#On transforme les valeurs qui sont des string et qui ont des virgules ...
# ...en valeurs numériques avec des points comme séparateur décimal
tableau2=Creation_Tableau(tableau1)

print(tableau2)




Page 10