Чтение таблиц в pandas: частые ошибки и как их обойти
Кодировка, разделители, типы столбцов и молчаливая потеря данных — четыре места, где чтение CSV и Excel в pandas ломается чаще всего. Разбираем, что происходит и как читать таблицы предсказуемо.

Вы открываете файл через pd.read_csv('data.csv'), а в датафрейме один столбец вместо десяти, даты стали строками, а телефонные номера потеряли ведущий ноль. Файл при этом нормально открывается в Excel. Проблема не в данных — проблема в том, что read_csv угадывает слишком многое и молча ошибается. Разберём четыре места, где чтение таблиц в pandas ломается чаще всего, и как заставить парсер вести себя предсказуемо.
Всё ниже проверено на pandas 2.x и Python 3.11. Часть поведения (движки парсинга, обработка типов) менялась между версиями 1.x и 2.x — где это важно, отмечаю отдельно.
Ошибка 1. Разделитель угадан неправильно
Классика: файл называется CSV, но внутри разделены не запятой, а точкой с запятой — так экспортирует Excel в русской локали, где запятая занята под десятичный разделитель. Результат — весь ряд попадает в один столбец.
# Файл с разделителем ; и десятичной запятой
import pandas as pd
df = pd.read_csv(
'export.csv',
sep=';', # разделитель столбцов
decimal=',', # запятая как десятичный разделитель
)
print(df.shape) # проверьте: столбцов должно быть столько, сколько ждёте
Если разделитель заранее неизвестен, можно попросить pandas определить его самостоятельно движком на Python:
# sep=None включает автоопределение, но требует engine='python'
df = pd.read_csv('export.csv', sep=None, engine='python')
Автоопределение работает не всегда и медленнее движка на C. Для регулярных загрузок лучше зафиксировать разделитель явно, чем полагаться на угадывание.
Ошибка 2. Кодировка не UTF-8
Второе по частоте — UnicodeDecodeError на файлах из российских систем, где часто встречается windows-1251. По умолчанию read_csv читает как UTF-8 и падает на первом же кириллическом символе в неожиданной кодировке.
# Файл в windows-1251 (cp1251)
df = pd.read_csv('vygruzka.csv', encoding='windows-1251', sep=';')
Если кодировка неизвестна, определите её до чтения. Библиотека charset-normalizer идёт зависимостью многих пакетов и умеет угадывать:
from charset_normalizer import from_path
result = from_path('vygruzka.csv').best()
print(result.encoding) # например, 'cp1251'
Угадывание кодировки — эвристика, а не гарантия. На коротких файлах оно ошибается. Если источник стабильный, узнайте кодировку у того, кто отдаёт файл, и захардкодьте её.
Молчаливая ошибка страшнее падения. UnicodeDecodeError вы заметите сразу. А вот неверно угаданный тип столбца пройдёт незамеченным до момента, когда на нём сломается расчёт в проде.
Ошибка 3. Типы столбцов угаданы неверно
pandas сам решает тип каждого столбца по его содержимому. Три типичных провала:
- Ведущие нули теряются. Столбец с кодами вроде
00123или ИНН превращается в целое число, ноль отваливается. - Смешанный столбец становится object. Если в числовой колонке попалась строка
«н/д», весь столбец читается как текст, и арифметика по нему падает. - Даты остаются строками. pandas 2.x по умолчанию не парсит даты — их нужно указывать явно.
Управляйте типами через dtype, а даты — через parse_dates:
df = pd.read_csv(
'clients.csv',
sep=';',
dtype={
'inn': 'string', # ИНН — строка, чтобы сохранить нули
'zip_code': 'string', # почтовый индекс тоже
},
parse_dates=['created_at'], # столбец с датами
na_values=['н/д', 'нет данных', '-'], # что считать пропуском
)
print(df.dtypes) # проверьте типы после чтения
Параметр na_values решает проблему смешанных столбцов: перечислите строки-заглушки, и pandas заменит их на NaN, оставив колонку числовой. Проверяйте результат через df.dtypes — это единственный надёжный способ убедиться, что типы такие, как вы ждёте.
Даты в неочевидном формате
Если дата записана как 25.12.2024, автопарсер может перепутать день и месяц. Задайте формат явно через date_format (доступен в pandas 2.x):
df = pd.read_csv(
'orders.csv',
parse_dates=['order_date'],
date_format='%d.%m.%Y', # день.месяц.год
)
В pandas 1.x аналогичного параметра нет — там дату парсили отдельно через pd.to_datetime(df['order_date'], format='%d.%m.%Y') после чтения.
Ошибка 4. Excel читается не с того листа и не с той строки
С файлами .xlsx свои грабли. read_excel по умолчанию берёт первый лист и считает первую строку заголовком. Но в реальных выгрузках сверху часто идут пустые строки, логотип или «Отчёт за период».
# Лист называется 'Продажи', шапка начинается с 4-й строки (индекс 3)
df = pd.read_excel(
'report.xlsx',
sheet_name='Продажи', # имя листа, а не индекс
header=3, # строка с заголовками (счёт с 0)
engine='openpyxl', # движок для .xlsx
)
Для чтения .xlsx нужен установленный openpyxl — иначе получите ImportError. Для старого формата .xls потребуется отдельный пакет xlrd, и там свои ограничения по версиям.
Сравнение параметров под задачу
| Проблема | Параметр | Что делает |
|---|---|---|
| Один столбец вместо многих | sep | Задаёт разделитель столбцов |
| Кракозябры или UnicodeDecodeError | encoding | Задаёт кодировку файла |
| Потеря ведущих нулей | dtype | Фиксирует тип столбца |
| Заглушки ломают числовой столбец | na_values | Помечает строки как пропуски |
| Даты остались строками | parse_dates | Парсит указанные столбцы в даты |
| Не тот лист или шапка в Excel | sheet_name, header | Выбирает лист и строку заголовка |
Ошибка 5. Большой файл съедает всю память
По умолчанию read_csv загружает файл целиком в память, а типы (особенно object для строк) раздувают его в разы против размера на диске. Файл на 2 ГБ легко превращается в 6–8 ГБ в оперативке. Если данные не помещаются, читайте кусками через chunksize:
# Обработка по 100 000 строк за раз
total = 0
for chunk in pd.read_csv('huge.csv', chunksize=100_000):
total += chunk['amount'].sum() # агрегируем по кускам
print(total)
Здесь read_csv возвращает итератор, а не датафрейм. Так вы держите в памяти только один кусок за раз. Если нужны все данные целиком, но памяти мало — смотрите в сторону формата Parquet вместо CSV: он колоночный, сжат и читается быстрее. Выбор формата хранения — отдельная тема, здесь только отмечаю направление.
Что делать дальше
Заведите привычку: после каждого чтения таблицы вызывайте df.info() и df.head(). Первое покажет типы и количество непустых значений по столбцам, второе — что реально прочиталось. Большинство молчаливых ошибок видны именно в этот момент, а не через неделю в отчёте.
Дальше стоит посмотреть на валидацию схемы: библиотека pandera позволяет описать ожидаемые типы и диапазоны столбцов и падать сразу при чтении, если данные не соответствуют. Для регулярных загрузок это дешевле, чем ловить кривые данные вручную.
Магистр Excel и Google Sheets: ВПР, СУММЕСЛИМН, макросы VBA и скрипты Apps Script.
Спросить за 20 ₽Источники: pandas.read_csv — официальная документация, pandas.read_excel — официальная документация
Частые вопросы
У меня pandas 1.x, часть примеров не работает
Как понять, какая у файла кодировка, если её никто не знает
Читаю Excel, а pandas выдаёт ImportError про openpyxl
Столбец с ИНН или индексом читается как число и теряет нули — как исправить
Файл слишком большой и Python падает с MemoryError
Как проверить, что таблица прочиталась правильно, а не молча съехала
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.