Урок по треку Python для анализа данных 6 мин

Чтение и запись данных в pandas

CSV, Excel, Parquet, SQL, JSON, кодировки, chunksize, dtype при чтении.

Половина багов в анализе случается на первой строке: при чтении файла. Неверный разделитель, потерянные ведущие нули, «NA» как пропуск, кодировка Windows-1251. На собесе это проверяют вопросами «почему у вас id стали числами» и «как прочитать файл на 20 ГБ».

CSV: главные параметры read_csv

import pandas as pd

df = pd.read_csv(
    'orders.csv',
    sep=';',               # в русских выгрузках из Excel часто точка с запятой
    decimal=',',           # и запятая в дробях
    encoding='cp1251',     # старые выгрузки 1С и Excel; по умолчанию utf-8
    dtype={'inn': 'string', 'zip': 'string'},
    parse_dates=['created_at'],
    usecols=['inn', 'zip', 'amount', 'created_at'],
)
  • dtype для идентификаторов. ИНН, индексы, артикулы 007 без явного dtype станут числами, ведущие нули пропадут, а длинные номера могут превратиться во float с потерей точности.
  • decimal. Без decimal=',' колонка 12,5 прочитается строкой, и sum() склеит строки или упадёт.
  • usecols читает только нужные колонки: меньше памяти и быстрее.
  • parse_dates сразу разбирает даты. Без него даты останутся строками.

Пропуски при чтении

По умолчанию пустая ячейка и строки вроде NA, NaN, null, N/A становятся NaN. Иногда это ломает данные: код страны Намибии NA или фамилия Null станут пропуском. Управление:

pd.read_csv(f, keep_default_na=False, na_values=[''])

Колонка целых чисел с пропуском превращается во float (1.0, NaN, 3.0). Чтобы остались целые, используйте nullable-тип: dtype={'qty': 'Int64'}.

Большие файлы

Если файл не влезает в память:

total = 0
for chunk in pd.read_csv('big.csv', chunksize=1_000_000, usecols=['amount']):
    total += chunk['amount'].sum()

chunksize возвращает итератор кусков, каждый кусок обычный DataFrame. Агрегаты, которые можно сложить (сумма, число строк, минимум), считаются по кускам и объединяются. Медиану и уникальные так не посчитать в лоб: нужны другие приёмы или другой инструмент (DuckDB, Polars, Spark).

Parquet вместо CSV

df.to_parquet('orders.parquet')        # нужен pyarrow
df = pd.read_parquet('orders.parquet', columns=['user', 'amount'])

Parquet колоночный и бинарный: хранит типы (даты остаются датами, category остаётся категорией), сжат, читает только нужные колонки. На тех же данных он обычно в разы меньше и быстрее CSV. Для промежуточных результатов анализа почти всегда лучше CSV.

Excel

pd.read_excel('report.xlsx', sheet_name='Продажи', skiprows=2)
pd.read_excel('report.xlsx', sheet_name=None)   # словарь всех листов

Нужен пакет openpyxl. Excel медленный и капризный: объединённые ячейки, шапки в несколько строк, даты числами. Для больших данных просите выгрузку в CSV или Parquet.

SQL

from sqlalchemy import create_engine
engine = create_engine('postgresql+psycopg://user:pass@host/db')
df = pd.read_sql('SELECT user_id, amount FROM orders WHERE created_at >= %(d)s',
                 engine, params={'d': '2026-10-01'})

Фильтры и агрегаты выгоднее делать в базе: тащить миллион строк в pandas, чтобы потом посчитать сумму, неэффективно. Параметры передавайте через params, а не форматированием строки: это защита от SQL-инъекций.

JSON

pd.read_json читает плоские JSON. Вложенные ответы API разворачивает pd.json_normalize:

pd.json_normalize(records)  # {'user': {'city': 'Казань'}} станет колонкой user.city

Запись

  • to_csv(path, index=False): без index=False в файл уйдёт лишняя безымянная колонка индекса.
  • Для Excel в русской локали: to_csv(..., sep=';', encoding='utf-8-sig'), иначе Excel покажет кракозябры.

Частые ошибки

  • ID без dtype=str потеряли ведущие нули.
  • Неверный sep или decimal: всё в одной колонке или числа строками.
  • NA как реальное значение превратилось в пропуск.
  • Выгрузили миллионы строк из БД ради одной суммы.
  • Сохранили промежуточные данные в CSV и потеряли типы.

Что спросят на собесе

  • Почему после чтения CSV пропали ведущие нули и как это исправить?
  • Как прочитать файл, который не помещается в память?
  • Чем Parquet лучше CSV?
  • Почему колонка целых чисел стала float?
  • Как безопасно передать параметры в SQL-запрос из pandas?

Закрепите за 5 минут

После урока в тренажёре 3-5 проверочных вопросов, дальше модуль уходит в повторения.