UnicodeDecodeError при чтении CSV-файла в Pandas с Python

412

Я запускаю программу, которая обрабатывает 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

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

TravisVOX
источник

Ответы:

824

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

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

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

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

Стефан
источник
7
Поскольку это проблема Windows, cp1252может быть предпочтительнее iso-8859-1.
tzot
7
Спасибо, pd.read_csv('immigration.csv', encoding = "ISO-8859-1", engine='python')сработало для меня
Мона Джалал
8
Не думайте слепо, что определенная кодировка является правильной только потому, что не выдается никаких исключений. Вам нужно взглянуть на строки и понять, имеет ли смысл интерпретация. Например, если вы получаете «hors d'½uvre» вместо «hors d'œuvre», вам, вероятно, нужно перейти с ISO-8859-1 на ISO-8859-15.
Иоахим Вагнер
6
для меня кодировка была ANSI. Чтобы выяснить это, я открыл csv, notepadзатем щелкнул save as, там он показывает кодировку рядом с кнопкой сохранения.
Вайбхав Вишал
69

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

import pandas as pd
df = pd.read_csv('file_name.csv', engine='python')

Альтернативное решение:

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

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

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

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

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

encoding = "cp1252"
encoding = "ISO-8859-1"
Джил Баджо
источник
11
Вопрос объясняет, что существует 30 000 таких файлов. Открытие каждого файла вручную не будет практичным.
Кит
4
ну хотя бы для одного файла, мне показалось, что это работает!
apil.tamang
Двигатель C, очевидно, более прощающий в том, что он принимает. Для конкретного CSV-файла, который открывается нормально с encoding='iso-8859-1'использованием вместо engine='python'throws _csv.Error: field larger than field limit (131072).
Грег Бэкон
1
альтернативное решение использовать сохранение с кодировкой было действительно полезно! вот как использовать его для VSCode stackoverflow.com/questions/30082741/…
brownmagik352
20

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, который был отредактирован в редакторе, отличном от utf8, и содержит несколько строк с другой кодировкой. В Pandas нет специальной обработки ошибок, но openфункция Python имеет (предполагается Python3) и read_csvпринимает файл, подобный объекту. Типичный параметр ошибок, который здесь используется, это то, 'ignore'что просто подавляет ошибочные байты или (IMHO лучше), 'backslashreplace'который заменяет ошибочные байты на обратную escape-последовательность их Python:

    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, ...)
Серж Баллеста
источник
1
Поздний ответ, но нацелен на повторяющийся вопрос ...
Серж Баллеста
14
with open('filename.csv') as f:
   print(f)

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

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

вот и ты

Bhavesh
источник
6

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

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

Водяников Андрей Анатольевич
источник
4

В моем случае это работает для 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) 
Виктор Вильакорта
источник
3

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

df = pd.read_csv(input_file_path,...engine='python')
Jan33
источник
Это также сработало для меня. Так же и кодировка = "ISO-8859-1". Это определенно проблема кодирования. Если в ANSI закодирован специальный символ, например, символ эллипса (то есть «...»), и вы пытаетесь прочитать его в UTF-8, вы можете получить ошибку. В итоге вы должны знать кодировку, с которой был создан файл.
Шон Маккарти
3

Я публикую ответ для предоставления обновленного решения и объяснения причин возникновения этой проблемы. Скажем, вы получаете эти данные из базы данных или книги Excel. Если у вас есть специальные символы, например La Cañada Flintridge city, если вы не экспортируете данные с использованием UTF-8кодировки, вы будете вводить ошибки. La Cañada Flintridge cityстанет La Ca\xf1ada Flintridge city. Если вы используете pandas.read_csvбез каких-либо настроек параметров по умолчанию, вы получите следующую ошибку

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xf1 in position 5: invalid continuation byte

К счастью, есть несколько решений.

Вариант 1 , исправить экспорт. Обязательно используйте UTF-8кодировку.

Вариант 2 , если фиксируя экспортирующей проблему не доступны для вас, и вы должны использовать pandas.read_csv, обязательно включают в себя следующие paramters, engine='python'. По умолчанию, pandas использует, engine='C'который отлично подходит для чтения больших чистых файлов, но вылетит, если произойдет что-то неожиданное. По моему опыту, установка encoding='utf-8'никогда не исправляла это UnicodeDecodeError. Кроме того, вам не нужно использовать errors_bad_lines, однако, это все еще вариант, если он действительно вам нужен.

pd.read_csv(<your file>, engine='python')

Вариант 3: решение - мое предпочтительное решение лично. Прочитайте файл, используя ванильный Python.

import pandas as pd

data = []

with open(<your file>, "rb") as myfile:
    # read the header seperately
    # decode it as 'utf-8', remove any special characters, and split it on the comma (or deliminator)
    header = myfile.readline().decode('utf-8').replace('\r\n', '').split(',')
    # read the rest of the data
    for line in myfile:
        row = line.decode('utf-8', errors='ignore').replace('\r\n', '').split(',')
        data.append(row)

# save the data as a dataframe
df = pd.DataFrame(data=data, columns = header)

Надеюсь, что это помогает людям, сталкивающимся с этой проблемой впервые.

Джон
источник
2

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

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

Дж. Тернент
источник
2

Пожалуйста, попробуйте добавить

encoding='unicode_escape'

Это поможет. Работал на меня. Также убедитесь, что вы используете правильный разделитель и имена столбцов.

Вы можете начать с загрузки всего 1000 строк, чтобы быстро загрузить файл.

Прахар Рати
источник
1

Этот ответ, кажется, является всеобъемлющим для проблем кодирования 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'), ... ])

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

nbwoodward
источник
1

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

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

tshirtdr1
источник
Nisse, спасибо за редактирование. Можете ли вы объяснить, что вы изменили? Я не вижу разницы.
tshirtdr1
1

У меня проблемы с открытием файла CSV на упрощенном китайском, загруженного из онлайн-банка. Я пытался latin1, я пытался iso-8859-1, я пытался cp1252, но все безрезультатно.

Но pd.read_csv("",encoding ='gbk')просто делает работу.

Люк Арон
источник
0

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

Химаншу Шарма
источник
0

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

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

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

Ке Сюй
источник
0

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

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

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

В питоне 3.7

DaveP
источник
0

Другая важная проблема, с которой я столкнулся, которая привела к той же самой ошибке, была:

_values = pd.read_csv("C:\Users\Mujeeb\Desktop\file.xlxs")

^ Эта строка вызвала ту же ошибку, потому что я читаю файл Excel, используя read_csv()метод. Используйте read_excel()для чтения .xlxs

Муджиб Исак
источник
Вау, все остальные говорят о проблемах кодирования. Похоже, моя проблема была особенной.
Муджиб Исак
Это потому, что у вас есть read_excelв пандах.
Ани Менон
0

Вы можете попробовать это.

import csv
import pandas as pd
df = pd.read_csv(filepath,encoding='unicode_escape')
Дилип Доминик
источник