Lire et écrire des fichiers CSV en Python

Vous voulez lire ou écrire des données dans un fichier CSV. Pour la plupart des types de fichiers CSV, utilisez la bibliothèque csv. Par exemple, supposons que vous ayez des données boursières dans un fichier nommé stocks.csv comme ceci:

Symbole,Prix,Date,Heure,Change,Vol
"ABBBA",33.48,"6/02/2018","3:42am",-0.18,181855
"AIGGG",71.38,"6/02/2018","3:42am",-0.15,135555
"ACCCXP",62.58,"6/02/2018","3:42am",-0.46,335550
"BGGGA",38.31,"6/02/2018","3:42am",+0.12,104855
"CVB",53.08,"6/02/2018","3:42am",-0.25,420355
"CATPO",78.23,"6/02/2018","3:42am",-0.23,225455

Voici comment lire les données comme une séquence de tuples:

import csv
with open('stocks.csv') as f:
    f_csv = csv.reader(f)
    en_tetes = next(f_csv)
    for ligne in f_csv:
        # traiter la ligne
        ...

Dans le code précédent, la ligne sera un tuple. Ainsi, pour accéder à certains champs, vous devrez utiliser l’indexation, comme ligne[0] (symbole) et ligne[4] (Change).

Comme une telle indexation peut souvent créer une confusion, c’est un endroit où vous voudrez peut-être envisager l’utilisation de tuples nommés. Par exemple:

from collections import namedtuple
with open('stock.csv') as f:
    f_csv = csv.reader(f)
    en_tetes = next(f_csv)
    Ligne = namedtuple('Ligne', en_tetes)
    for r in f_csv:
        ligne = Ligne(*r)
        # Continuer le traitement
        ...

Ceci vous permettrait d’utiliser les en-têtes de colonne tels que ligne.Symbol et ligne.Change à la place des index.

Il est à noter que cela ne fonctionne que si les en-têtes de colonne sont des identifiants Python valides.

Si ce n’est pas le cas, vous devrez peut-être modifier les en-têtes initiaux (p. ex. remplacer les caractères non identificateurs par des tirets de soulignement ou autres).

Une autre alternative est de lire les données comme une séquence de dictionnaires à la place. Pour ce faire, utilisez ce code:

import csv
with open('stocks.csv') as f:
    f_csv = csv.DictReader(f)
    for ligne in f_csv:
        # process row
        ...

Dans cette version, vous accédez aux éléments de chaque ligne à l’aide des en-têtes de ligne. Par exemple, ligne[‘Symbole’] ou lgne[‘Change’].

Pour écrire des données dans un fichiers CSV, vous utilisez également le module csv mais vous créez un objet writer. Par exemple:

en_tetes = ['Symbol','Prix','Date','Heure','Change','Vol']
lignes = [('AB', 30, '6/2/2018', '8:11am', -0.28, 15500),
        ('KJL', 55, '6/2/2018', '8:11am', -0.95, 445500),
        ('MMP', 88, '6/2/2018', '8:11am', -0.26, 966000),
       ]

with open('stocks.csv','w') as f:
    f_csv = csv.writer(f)
    f_csv.writerow(en_tetes)
    f_csv.writerows(lignes)

Si vous disposez des données sous la forme d’une séquence de dictionnaires, procédez comme suit:

en_tetes = ['Symbole', 'Prix', 'Date', 'Heure', 'Change', 'Vol']
lignes = [{'Symbole':'HHA', 'Prix':350.48, 'Date':'6/1/2018',
          'Heure':'50:36am', 'Change':-0.58, 'Vol':585855},
        {'Symbole':'NNG', 'Prix': 75.38, 'Date':'6/1/2018',
          'Heure':'50:36am', 'Change':-0.55, 'Vol': 5505555},
        {'Symbole':'UOP', 'Prix': 62.58, 'Date':'6/1/2018',
          'Heure':'50:36am', 'Change':-0.46, 'Vol': 5035550},
        ]

with open('stocks.csv','w') as f:
    f_csv = csv.DictWriter(f, en_tetes)
    f_csv.writeheader()
    f_csv.writerows(lignes)

Vous devriez presque toujours préférer l’utilisation du module csv plutôt que d’essayer manuellement de parser et d’analyser les données CSV vous-même. Par exemple, vous pourriez être enclin à écrire un code comme celui-ci:

with open('stocks.csv') as f:
    for ligne in f:
        ligne = ligne.split(',')
        # traiter la ligne
        ...

Le problème avec cette approche, c’est que vous devrez quand même vous occuper de certains détails désagréables. Par exemple, si l’un des champs est entouré de guillemets, vous devrez les supprimer.

De plus, si un champ entre guillemets contient une virgule, le code se brise en produisant une ligne de mauvaise taille.

Par défaut, la bibliothèque csv est programmée pour comprendre les règles d’encodage CSV utilisées par Microsoft Excel. C’est probablement la variante la plus courante et elle vous donnera probablement la meilleure compatibilité.

Cependant, si vous consultez la documentation du module csv, vous verrez quelques façons d’ajuster l’encodage à différents formats (par exemple, changer le caractère de séparation, etc.). Par exemple, si vous voulez lire des données délimitées par des tabulations à la place, utilisez ceci:

# Exemple de lecture de valeurs séparées par des tabulations
with open('stock.tsv') as f:
    f_tsv = csv.reader(f, delimiter='\t')
    for row in f_tsv:
        # Traiter la ligne
        ...

vous lisez des données CSV et les convertissez en tuples nommés, vous devez être un peu prudent avec la validation des en-têtes de colonnes.

Par exemple, un fichier CSV pourrait avoir une ligne d’en-tête contenant des caractères d’identification non valides comme ceci:

Adresse,Ville,Latitude,Longitude
200 Avenue B,10,31.980262,-77.668452

Ceci provoquera l’échec de la création d’un objet namedtuple avec une exception ValueError. Pour contourner ce problème, vous devrez peut-être d’abord frotter les en-têtes.

Par exemple, porter une substitution d’expression régulière sur des caractères d’identification non valides comme ceci:

import re
with open('stock.csv') as f:
    f_csv = csv.reader(f)
    en_tetes = [ re.sub('[^a-zA-Z_]', '_', h) for h in next(f_csv) ]
    Lignes = namedtuple('Lignes', en_tetes)
    for r in f_csv:
        ligne = Lignes(*r)
        # Traiter la ligne
        ...

Il est également important de souligner que csv n’essaie pas d’interpréter les données ou de les convertir en un type autre qu’une chaîne de caractères. Si de telles conversions sont importantes, c’est quelque chose que vous devrez faire vous-même.

Voici un exemple de conversion de type supplémentaire sur des fichiers CSV:

col_types = [str, float, str, str, float, int]
with open('stocks.csv') as f:
    f_csv = csv.reader(f)
    en_tetes = next(f_csv)
    for ligne in f_csv:
        # Appliquer les conversions aux éléments de la ligne
        ligne = tuple(convert(valeur) for convert, valeur  in zip(col_types, ligne))
        ...

Alternativement, voici un exemple de conversion de champs sélectionnés de dictionnaires:

print(''Lecture en tant que dict avec conversion de type')
field_types = [ ('Prix', float),
                ('Change', float),
                ('Vol', int) ]

with open('stocks.csv') as f:
    for ligne in csv.DictReader(f):
        ligne.update((cle, conversion(ligne[cle]))
                   for cle, conversion in field_types)
        print(ligne)

En général, vous voudrez probablement être un peu prudent avec de telles conversions, cependant.

Dans le monde réel, il est courant que les fichiers CSV aient des valeurs manquantes, des données corrompues et d’autres problèmes qui pourraient briser les conversions de type.

Ainsi, à moins que vos données ne soient garanties sans erreur, c’est quelque chose que vous devrez prendre en compte (vous devrez peut-être ajouter une gestion d’exceptions appropriée).

Enfin, si votre objectif en lisant les données CSV est d’effectuer des analyses de données et des statistiques, vous voudrez peut-être consulter le package Pandas.

Pandas inclut une fonction pratique pandas.read_csv() qui chargera les données CSV dans un objet DataFrame.

À partir de là, vous pouvez générer diverses statistiques sommaires, filtrer les données et effectuer d’autres types d’opérations de haut niveau.

LAISSER UN COMMENTAIRE

Please enter your comment!
Please enter your name here