UnicodeDecodeError при чтении CSV файла в Pandas с помощью Python

Я запускаю программу, которая обрабатывает 30 000 подобных файлов. Случайное число из них останавливается и создает эту ошибку...

   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

Источник/создание этих файлов происходит из одного и того же места. Каков наилучший способ исправить это, чтобы продолжить импорт?

Ответ 1

read_csv использует опцию encoding для работы с файлами в разных форматах. В основном я использую read_csv('file', encoding = "ISO-8859-1") или, альтернативно, encoding = "utf-8" для чтения, и обычно utf-8 для to_csv.

Вы также можете использовать одну из нескольких опций alias, например 'latin', вместо 'ISO-8859-1' (см. документы по питону, а также множество других кодировок, с которыми вы можете столкнуться).

См. соответствующую документацию Pandas, Python Docs примеры на CSV файлах, и множество связанных с этим вопросов здесь, на SO. Хороший фоновый ресурс - это что каждый разработчик должен знать о юникоде и наборах символов.

Чтобы определить кодировку (при условии, что файл содержит символы, отличные от ascii), вы можете использовать enca (см. man-страницу) или file -i (linux) или file -I (osx) (см. справочная страница).

Ответ 2

Самый простой из всех решений:

  • Откройте файл csv в текстовом редакторе Sublime.
  • Сохраните файл в формате utf-8.

В возвышенном виде нажмите "Файл" → "Сохранить с кодировкой" → UTF-8

Затем вы можете прочитать свой файл как обычно:

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

ИЗМЕНИТЬ 1:

Если файлов много, вы можете пропустить возвышенный шаг.

Просто прочитайте файл, используя

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

и другие различные типы кодирования:

encoding = "cp1252"
encoding = "ISO-8859-1"

Ответ 3

Pandas позволяет указывать кодировку, но не позволяет игнорировать ошибки, чтобы не автоматически заменять оскорбительные байты. Таким образом, ни один из них не подходит для всех методов, но по-разному в зависимости от фактического варианта использования.

  1. Вы знаете кодировку, и в файле нет ошибки кодирования. Отлично: вам нужно просто указать кодировку:

    file_encoding = 'cp1252'        # set file_encoding to the file encoding (utf8, latin1, etc.)
    pd.read_csv(input_file_and_path, ..., encoding=file_encoding)
    
  2. Вы не хотите, чтобы вас беспокоили вопросы кодирования, и только хотите, чтобы этот проклятый файл загружался, независимо от того, содержат ли какие-то текстовые поля мусор. Хорошо, вам нужно использовать только кодировку Latin1 потому что она принимает любой возможный байт в качестве входа (и преобразует его в символ Юникода того же кода):

    pd.read_csv(input_file_and_path, ..., encoding='latin1')
    
  3. Вы знаете, что большая часть файла написана с определенной кодировкой, но также содержит ошибки в кодировке. Пример реального мира - это файл UTF8, который был отредактирован с помощью редактора un utf8 и который содержит некоторые строки с другой кодировкой. Pandas не предусматривает специальной обработки ошибок, но open функция Python имеет (предполагая Python3), а read_csv принимает файл, подобный объекту. Типичным параметром ошибок, который здесь используется, является 'ignore' который просто подавляет оскорбительные байты или (ИМХО лучше) 'backslashreplace' который заменяет оскорбительные байты их защитой от обратного перехода Pythons:

    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, ...)
    

Ответ 4

with open('filename.csv') as f:
   print(f)

после выполнения этого кода вы найдете кодировку 'filename.csv', затем выполните код следующим образом

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

вот и ты

Ответ 5

Попробуйте указать engine = 'python'. Это сработало для меня, но я все еще пытаюсь понять, почему.

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

Ответ 6

Некоторое время боролся с этим и думал, что я опубликую этот вопрос, так как это первый результат поиска. Добавление тега encoding="iso-8859-1" к пандам read_csv не работало, и никакие другие кодировки не давали UnicodeDecodeError.

Если вы передаете дескриптор файла в pd.read_csv(),, вам нужно поместить атрибут encoding в открытый файл, а не в read_csv. Очевидно, задним числом, но тонкая ошибка, чтобы выследить.

Ответ 7

В моем случае файл имеет кодировку "USC-2 LE BOM", согласно Notepad++. Это кодировка = "utf_16_le" для Python.

Надеюсь, это поможет кому-то быстрее найти ответ.

Ответ 8

В моем случае это работало для Python 2.7:

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

И только для Python 3:

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

Ответ 9

Этот ответ, кажется, является всеобъемлющим для проблем кодирования CSV. Если вы получаете странную проблему с кодировкой вашего заголовка, например:

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

Тогда у вас есть символ метки порядка байтов (BOM) в начале вашего CSV файла. Этот ответ решает проблему:

Python read csv - спецификация, встроенная в первый ключ

Решение состоит в том, чтобы загрузить CSV с encoding="utf-8-sig":

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

Надеюсь, это кому-нибудь поможет.

Ответ 10

Я публикую обновление в этой старой теме. Я нашел одно решение, которое сработало, но требует открытия каждого файла. Я открыл свой CSV файл в LibreOffice, выбрал "Сохранить как"> "Изменить настройки фильтра". В выпадающем меню я выбрал кодировку UTF8. Затем я добавил encoding="utf-8-sig" в data = pd.read_csv(r'C:\fullpathtofile\filename.csv', sep = ',', encoding="utf-8-sig").

Надеюсь, это кому-нибудь поможет.

Ответ 11

Я использую Jupyter-ноутбук. И в моем случае, он показывал файл в неправильном формате. Опция "кодирование" не работала. Поэтому я сохраняю CSV в формате UTF-8, и это работает.

Ответ 12

Попробуйте это:

import pandas as pd
with open('filename.csv') as f:
    data = pd.read_csv(f)

Похоже, он позаботится о кодировке без явного выражения через аргумент

Ответ 13

Проверьте кодировку, прежде чем переходить к пандам. Это замедлит тебя, но...

with open(path, 'r') as f:
    encoding = f.encoding 

df = pd.read_csv(path,sep=sep, encoding=encoding)

В питоне 3.7