web-dev-qa-db-fra.com

UnicodeDecodeError lors de la lecture d'un fichier CSV dans les pandas avec Python

J'exécute un programme qui traite 30 000 fichiers similaires. Un nombre aléatoire d'entre eux s'arrêtent et produisent cette erreur ...

   File "C:\Importer\src\dfman\importer.py", line 26, in import_chr
     data = pd.read_csv(filepath, names=fields)
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 400, in parser_f
     return _read(filepath_or_buffer, kwds)
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 205, in _read
     return parser.read()
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 608, in read
     ret = self._engine.read(nrows)
   File "C:\Python33\lib\site-packages\pandas\io\parsers.py", line 1028, in read
     data = self._reader.read(nrows)
   File "parser.pyx", line 706, in pandas.parser.TextReader.read (pandas\parser.c:6745)
   File "parser.pyx", line 728, in pandas.parser.TextReader._read_low_memory (pandas\parser.c:6964)
   File "parser.pyx", line 804, in pandas.parser.TextReader._read_rows (pandas\parser.c:7780)
   File "parser.pyx", line 890, in pandas.parser.TextReader._convert_column_data (pandas\parser.c:8793)
   File "parser.pyx", line 950, in pandas.parser.TextReader._convert_tokens (pandas\parser.c:9484)
   File "parser.pyx", line 1026, in pandas.parser.TextReader._convert_with_dtype (pandas\parser.c:10642)
   File "parser.pyx", line 1046, in pandas.parser.TextReader._string_convert (pandas\parser.c:10853)
   File "parser.pyx", line 1278, in pandas.parser._string_box_utf8 (pandas\parser.c:15657)
 UnicodeDecodeError: 'utf-8' codec can't decode byte 0xda in position 6: invalid    continuation byte

La source/création de ces fichiers proviennent tous du même endroit. Quelle est la meilleure façon de corriger cela pour procéder à l'importation?

214
TravisVOX

read_csv prend une option encoding pour traiter les fichiers dans différents formats. J'utilise principalement read_csv('file', encoding = "ISO-8859-1"), ou alternativement encoding = "utf-8" pour la lecture, et généralement utf-8 pour to_csv.

Vous pouvez également utiliser l'une des options alias telles que 'latin' au lieu de 'ISO-8859-1' (voir python docs , également pour de nombreux autres encodages que vous pourriez rencontrer).

Voir la documentation pertinente sur les pandas , des exemples de documents python sur les fichiers csv , ainsi que de nombreuses questions connexes sur les SO.

Pour détecter le codage (en supposant que le fichier contienne des caractères non-ASCII), vous pouvez utiliser enca (voir page de manuel ) ou file -i (Linux) ou file -I (osx) (voir page de manuel ). 

499
Stefan

La solution la plus simple:

  • Ouvrez le fichier csv dans l’éditeur de texte Sublime.
  • Enregistrez le fichier au format utf-8.

En sublime, cliquez sur Fichier -> Enregistrer avec encodage -> UTF-8

Ensuite, vous pourrez lire votre fichier comme d'habitude:

import pandas as pd
data = pd.read_csv('file_name.csv', encoding='utf-8')

EDIT 1:

S'il y a beaucoup de fichiers, vous pouvez alors ignorer l'étape sublime.

Il suffit de lire le fichier en utilisant

data = pd.read_csv('file_name.csv', encoding='utf-8')

et les autres types de codage différents sont:

encoding = "cp1252"
encoding = "ISO-8859-1"
20
Gil Baggio

Les pandas permettent de spécifier le codage, mais ne permettent pas d'ignorer les erreurs pour ne pas remplacer automatiquement les octets incriminés. Donc, il n'y a pas de méthode one size qui convient à tous, mais différentes manières en fonction du cas d'utilisation réel.

  1. Vous connaissez le codage et il n'y a pas d'erreur de codage dans le fichier. Super: il vous suffit de spécifier le codage:

    file_encoding = 'cp1252'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    pd.read_csv(input_file_and_path, ..., encoding=file_encoding)
    
  2. Vous ne voulez pas être dérangé par les questions d’encodage, vous voulez seulement que ce foutu fichier soit chargé, peu importe si certains champs de texte contiennent des ordures. Ok, vous devez seulement utiliser le codage Latin1 car il accepte tout octet possible en entrée (et le convertit en caractère unicode du même code):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
    
  3. Vous savez que la plupart du fichier est écrit avec un codage spécifique, mais il contient également des erreurs de codage. Un exemple concret est un fichier UTF8 qui a été édité avec un éditeur non-utf8 et qui contient des lignes avec un codage différent. Pandas ne prévoit pas de traitement d'erreur spécial, mais la fonction Python open a (en supposant Python3), et read_csv accepte un fichier comme un objet. Le paramètre d'erreur typique à utiliser ici est 'ignore' qui supprime simplement les octets incriminés ou (à mon humble avis) 'backslashreplace' qui remplace les octets incriminés par la séquence d'échappement Pashon inversée:

    file_encoding = 'utf8'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    input_fd = open(input_file_and_path, encoding=file_encoding, errors = 'backslashreplace')
    pd.read_csv(input_fd, ...)
    
6
Serge Ballesta
with open('filename.csv') as f:
   print(f)

après avoir exécuté ce code, vous trouverez le codage de 'nomfichier.csv', puis exécutez le code comme suit

data=pd.read_csv('filename.csv', encoding="encoding as you found earlier"

voilà

2
bhavesh

Cela fait un moment que je me débattais avec cela et je pensais poster sur cette question car il s’agit du premier résultat de recherche. L'ajout de la balise encoding = 'iso-8859-1 "aux pandas read_csv ne fonctionnait pas, aucun autre encodage ne continuait à donner une erreur UnicodeDecodeError 

Si vous passez un descripteur de fichier à pd.read_csv (), vous devez mettre l'attribut encoding = sur le fichier ouvert, pas dans read_csv. Évident après coup, mais une erreur subtile à traquer.

1
J. Ternent

Dans mon cas, cela a fonctionné pour python 2.7:

data = read_csv(filename, encoding = "ISO-8859-1", dtype={'name_of_colum': unicode}, low_memory=False) 

Et pour python 3, uniquement:

data = read_csv(filename, encoding = "ISO-8859-1", low_memory=False) 
1
Victor Villacorta

Cette réponse semble être la panacée pour les problèmes d'encodage CSV. Si vous rencontrez un problème de codage étrange avec votre en-tête, procédez comme suit:

>>> f = open(filename,"r")
>>> reader = DictReader(f)
>>> next(reader)
OrderedDict([('\ufeffid', '1'), ... ])

Ensuite, vous avez un caractère de marque d'ordre d'octet (BOM) au début de votre fichier CSV. Cette réponse aborde le problème:

Python read csv - BOM intégrée à la première clé

La solution consiste à charger le fichier CSV avec encoding="utf-8-sig":

>>> f = open(filename,"r", encoding="utf-8-sig")
>>> reader = DictReader(f)
>>> next(reader)
OrderedDict([('id', '1'), ... ])

Espérons que cela aide quelqu'un.

1
nbwoodward

J'utilise Jupyter-notebook. Et dans mon cas, il montrait le fichier dans le mauvais format. L'option 'encodage' ne fonctionnait pas. Donc, je sauve le csv au format utf-8, et ça marche.

0
Himanshu Sharma

Essayez de spécifier le moteur = 'python'. Cela a fonctionné pour moi mais j'essaie toujours de comprendre pourquoi.

df = pd.read_csv(input_file_path,...engine='python')
0
Jan33

Je publie une mise à jour de cet ancien fil de discussion. J'ai trouvé une solution qui a fonctionné, mais nécessite d'ouvrir chaque fichier. J'ai ouvert mon fichier csv dans LibreOffice, puis choisi Enregistrer sous> modifier les paramètres de filtre. Dans le menu déroulant, j'ai choisi le codage UTF8. Ensuite, j'ai ajouté encoding="utf-8-sig" à la data = pd.read_csv(r'C:\fullpathtofile\filename.csv', sep = ',', encoding="utf-8-sig").

J'espère que ça aide quelqu'un.

0
tshirtdr1

Dans mon cas, un fichier a l'encodage "USC-2 LE BOM", selon Notepad ++. C’est encoding = "utf_16_le" pour python. 

J'espère que ça aide de trouver une réponse un peu plus vite pour quelqu'un.