UnicodeDecodeError під час читання CSV-файлу в Pandas з Python


411

Я запускаю програму, яка обробляє 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

Джерело / створення цих файлів - усі з одного місця. Який найкращий спосіб виправити це, щоб продовжити імпорт?

Відповіді:


823

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(див. Man page ) або file -i(linux) або file -I(osx) (див. Man page ).


7
Оскільки це проблема Windows, cp1252можливо, буде кращим iso-8859-1.
tzot

7
Спасибі pd.read_csv('immigration.csv', encoding = "ISO-8859-1", engine='python')працювали для мене
Mona Jalal

8
Не слід сліпо вважати, що певне кодування є правильним лише тому, що не викинуто жодного винятку. Потрібно подивитися на рядки і розібратися, чи має сенс інтерпретація. Наприклад, якщо ви отримаєте "hors d'½uvre" замість "hors d'œuvre", вам, ймовірно, потрібно перейти з ISO-8859-1 на ISO-8859-15.
Йоахім Вагнер

6
для мене кодування було ANSI. Щоб зрозуміти це, я відкрив csv, notepadа потім натисніть save as, там він відображає кодування поруч із кнопкою збереження.
Вайбхав Вішал


68

Найпростіші з усіх рішень:

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'кидків _csv.Error: field larger than field limit (131072).
Грег Бекон

1
Альтернативне рішення використовувати Save з кодуванням було дуже корисно! ось як використовувати його для 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'який замінює байти-скривдики на послідовно відхилену послідовність втечі 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"

ось так


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

Спробуйте вказати двигун = 'python'. Це працювало для мене, але я все ще намагаюся з’ясувати, чому.

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

Це теж працювало для мене. Так само робилося кодування = "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"тегу до панд 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 прочитав csv - BOM вбудований у перший ключ

Рішення полягає в завантаженні CSV encoding="utf-8-sig":

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

Сподіваємось, це комусь допомагає.


1

Я публікую оновлення до цієї старої теми. Я знайшов одне рішення, яке працювало, але вимагає відкриття кожного файлу. Я відкрив свій файл csv у LibreOffice, вибрав Зберегти як> редагувати параметри фільтра. У спадному меню я вибрав кодування UTF8. Потім я додав encoding="utf-8-sig"до data = pd.read_csv(r'C:\fullpathtofile\filename.csv', sep = ',', encoding="utf-8-sig").

Сподіваюся, що це комусь допоможе.


Ніссе, дякую за редагування. Чи можете ви поясніть, що ви змінили? Я не бачу різниці.
tshirtdr1

1

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

Але pd.read_csv("",encoding ='gbk')просто виконує роботу.


0

Я використовую ноутбук Юпітер. І в моєму випадку він показував файл у неправильному форматі. Параметр «кодування» не працював. Тому я зберігаю 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


0

Ще одне важливе питання, з яким я зіткнувся, внаслідок якого стала та сама помилка:

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

^ Цей рядок призвів до тієї ж помилки, оскільки я читаю файл excel за допомогою read_csv()методу. Використовувати read_excel()для читання .xlxs


Нічого собі, всі інші говорять про проблеми кодування. Схоже, моє питання було своєрідним.
Mujeeb Ishaque

Це тому, що у вас є read_excelпанди.
Ані Менон

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.