Работа с датами в Python на собеседовании
Почему даты — обязательная тема
Аналитик работает с временными рядами каждый день: DAU, retention, когорты, сезонность. На собеседовании вопросы по датам проверяют, умеете ли вы обрабатывать реальные данные, а не только числовые колонки из учебника.
Формат вопросов разный: от «преобразуйте строку в дату» до «постройте скользящее среднее за 7 дней». Для junior достаточно знать datetime и pd.to_datetime, для middle — resample, rolling и работу с часовыми поясами.
Навык работы с датами в Python напрямую связан с SQL: если вы знаете DATE_TRUNC и EXTRACT, pandas-аналоги освоите за час. Интервьюеры часто просят решить одну задачу на обоих языках.
Стандартная библиотека datetime
datetime.datetime — основной класс для даты и времени. datetime.now() — текущий момент, datetime(2024, 3, 15) — конкретная дата. Атрибуты year, month, day, hour, minute, second доступны напрямую.
timedelta — разница между датами. timedelta(days=7) — неделя. Арифметика интуитивна: datetime.now() - timedelta(days=30) — дата 30 дней назад. Результат вычитания двух datetime — тоже timedelta.
strftime и strptime — форматирование и парсинг. dt.strftime('%Y-%m-%d') — из datetime в строку, datetime.strptime('2024-03-15', '%Y-%m-%d') — из строки в datetime. На собеседовании могут попросить вспомнить коды формата: %Y (год), %m (месяц), %d (день), %H (час).
pandas: pd.to_datetime и dt-аксессор
pd.to_datetime — конвертация колонки в datetime. Принимает строки в большинстве форматов автоматически. Параметр format ускоряет парсинг на больших данных: pd.to_datetime(df['date'], format='%Y-%m-%d').
dt-аксессор — доступ к компонентам даты через серию: df['date'].dt.year, df['date'].dt.month, df['date'].dt.dayofweek. Аналог EXTRACT в SQL. Используется для группировки по периодам и создания признаков.
Типичная ошибка: забыть конвертировать колонку через pd.to_datetime. Если колонка остаётся строкой, dt-аксессор недоступен, сортировка по дате работает некорректно, а фильтрация по диапазону даёт неожиданные результаты.
resample и rolling: временные агрегации
resample — группировка временного ряда по периодам. df.set_index('date').resample('W')['value'].sum() — сумма по неделям. Аналог GROUP BY DATE_TRUNC в SQL. Коды периодов: 'D' (день), 'W' (неделя), 'M' (месяц), 'Q' (квартал).
rolling — скользящее окно. df['value'].rolling(7).mean() — скользящее среднее за 7 точек. Параметр min_periods задаёт минимум наблюдений для расчёта — без него первые значения будут NaN.
Задача с собеседования: Посчитайте 7-дневное скользящее среднее DAU. Подход — сначала resample('D') для дневных агрегатов, затем rolling(7).mean(). Частая ошибка — применять rolling к негруппированным данным.
Часовые пояса и подводные камни
tz_localize и tz_convert — работа с часовыми поясами. df['date'].dt.tz_localize('UTC').dt.tz_convert('Europe/Moscow') — конвертация из UTC в московское время. Без локализации pandas считает даты «наивными» — без часового пояса.
NaT — аналог NaN для дат. Появляется при неудачном парсинге (если errors='coerce' в pd.to_datetime) или пропущенных значениях. NaT ведёт себя как NaN: любое сравнение возвращает False.
Смешанные форматы — если в одной колонке даты в разных форматах ('2024-03-15' и '15/03/2024'), pd.to_datetime без format попытается разобрать каждую строку отдельно. Это медленно и может дать ошибки. Лучше предварительно привести формат к единому.
Совет: всегда проверяйте тип колонки после загрузки данных через df.dtypes. Если видите object вместо datetime64 — конвертируйте явно через pd.to_datetime. Это спасёт от неочевидных ошибок.
FAQ
Чем resample отличается от groupby с dt.month?
resample работает только с DatetimeIndex и создаёт непрерывный временной ряд — пропущенные периоды заполняются NaN. groupby с dt.month возвращает только те месяцы, где есть данные. Для аналитических отчётов resample предпочтительнее — он не скрывает периоды без активности.
Как сравнить даты из разных часовых поясов?
Обе даты должны быть «осведомлёнными» (timezone-aware). Сравнение naive и aware дат вызовет ошибку. Приведите обе к одному часовому поясу через tz_convert или tz_localize, затем сравнивайте. На собеседовании достаточно знать этот принцип.
Спрашивают ли про dateutil или arrow?
Редко. На собеседовании аналитика достаточно знать стандартный datetime и pandas. dateutil полезен для парсинга нестандартных форматов, arrow — для удобной работы с часовыми поясами, но это библиотеки для разработчиков, а не для аналитиков. Больше тем — в разделе Python.