UnicodeDecodeError при чтении
pd.read_csv ждёт UTF-8. Если файл сохранён в Windows-1251 (ANSI), pandas падает с ошибкой UnicodeDecodeError: 'utf-8' codec can't decode byte 0xcf — 0xCF это «П» в Windows-1251. Тогда укажите кодировку:
pd.read_csv("data.csv", encoding="cp1251")для файлов из Excel, 1С и русской Windows.- Для старых файлов с серверов и из почты иногда нужны
encoding="koi8-r"(KOI8-R) илиencoding="cp866"(DOS). - Если кодировка неизвестна, перетащите файл в Mojibuster: он определит её и сохранит файл в UTF-8.
Привет вместо «Привет» в DataFrame
Если в DataFrame стоит Привет, файл в UTF-8 прочитан как cp1251 — или данные испорчены раньше. В первом случае достаточно encoding="utf-8". Если испорчены сами данные, для отдельных значений поможет value.encode("cp1251").decode("utf-8"). На смешанных данных это ломается, как только ячейка уже правильная. Проще исправить файл в Mojibuster и потом прочитать его.
До
имя,город,выручка Олег Петров,Санкт-Петербург,1250 ₽ Юлия Щербакова,Ярославль,980 ₽
После
имя,город,выручка Олег Петров,Санкт-Петербург,1250 ₽ Юлия Щербакова,Ярославль,980 ₽
to_csv: Excel показывает файл неправильно
df.to_csv("export.csv") пишет UTF-8 без BOM. Excel открывает такие файлы как ANSI, и русские буквы превращаются в Привет. С параметром encoding="utf-8-sig" pandas добавит BOM, и Excel распознает UTF-8. Для русского Excel также нужен sep=";". Подробнее: кракозябры в Excel.
open() в Windows
open("file.txt") без encoding в Windows использует системную кодировку, на русской Windows это обычно cp1251. Скрипт, который работает в Linux, в Windows прочитает тот же UTF-8-файл как Привет. Поэтому всегда указывайте encoding="utf-8" или задайте переменную окружения PYTHONUTF8=1. По PEP 686 UTF-8 станет кодировкой по умолчанию и в будущих версиях Python.
Данные из сети через requests
requests определяет response.text по заголовку Content-Type. Если в текстовом ответе кодировка не указана, библиотека предполагает ISO-8859-1, и страницы в UTF-8 показывают привет. Сначала задайте response.encoding = "utf-8" или используйте response.json(): он сам распознаёт UTF-8.
Если текст записан с errors="replace" в кодировку без нужных букв, в файле стоят ?. Тогда информация потеряна, подробнее в статье что такое кракозябры.
Частые вопросы
Есть ли для этого библиотека на Python?
Да, ftfy исправляет mojibake в коде на Python. Для отдельных файлов без программирования быстрее Mojibuster: он показывает каждое изменение перед сохранением.
Какие значения encoding нужны чаще всего?
utf-8, utf-8-sig (UTF-8 с BOM), cp1251 (Windows, кириллица), koi8-r, cp866 и utf-16. Регистр и дефисы не важны.
Сохраняются ли разделители и числа?
Да. Mojibuster меняет только испорченные символы. Запятые, кавычки и переносы строк остаются как есть.