← К списку уроков
Python·Средний·14 мин

Временные ряды в pandas

pd.to_datetime, resample, pct_change — анализ данных с датами.

Временные ряды в pandas

Дата-аналитик 80% работает с временными рядами: выручка по дням, регистрации по часам, retention по неделям. Pandas умеет в них всё.

datetime тип

df['date'] = pd.to_datetime(df['date'])

errors='coerce' — невалидные даты в NaT вместо ошибки:

pd.to_datetime(df['date'], errors='coerce')

Доступ к компонентам

Через аксессор .dt:

df['date'].dt.year
df['date'].dt.month
df['date'].dt.day
df['date'].dt.dayofweek    # 0 = Понедельник
df['date'].dt.day_name()   # 'Monday', 'Tuesday'
df['date'].dt.quarter
df['date'].dt.is_weekend   # ⚠ нет такого, нужен dayofweek >= 5

resample — агрегация по периодам

Самая мощная функция для timeseries. Требует индекс типа DateTime:

df = df.set_index('date')

df.resample('M').sum()   # по месяцам
df.resample('W').mean()  # по неделям (с воскресенья)
df.resample('D').count() # по дням
df.resample('H').max()   # по часам

Алиасы: D (день), W (неделя), M (месяц), Q (квартал), Y (год), H (час).

rolling — скользящие средние

df['ma_7d'] = df['sales'].rolling(window=7).mean()
df['ma_30d'] = df['sales'].rolling(30).mean()
df['cumsum'] = df['sales'].cumsum()

shift — сравнение со вчера/прошлой неделей

df['sales_prev'] = df['sales'].shift(1)
df['growth_pct'] = (df['sales'] - df['sales_prev']) / df['sales_prev']

# DoD (день к дню), WoW, YoY
df['yoy'] = df['sales'] / df['sales'].shift(365) - 1

Заполнение пропусков в датах

Если дни в данных нерегулярные (пропущены воскресенья) — asfreq:

df.asfreq('D', fill_value=0)

Timezone

df['date'].dt.tz_localize('Asia/Almaty')         # назначить timezone
df['date'].dt.tz_convert('UTC')                  # перевести в UTC

Что важно запомнить

  • Всегда конвертируй колонку с датой через pd.to_datetime — иначе всё разваливается
  • resample требует DatetimeIndex — ставь через set_index
  • DoW/WoW/YoY = .shift(N). Готовый паттерн для роста/убывания
  • Скользящая средняя сглаживает шум — для дневных метрик с большой дисперсией обязательна
  • На собеседовании DA: «как рассчитать MAU за каждый день» = df.resample('D').apply(lambda x: x['user_id'].nunique())