Как обработать даты в pandas

Карьерник — квиз-тренажёр в Telegram с 1500+ вопросами для собесов аналитика. SQL, Python, A/B, метрики. Бесплатно.

Парсинг дат

import pandas as pd

# строка → datetime
df['date'] = pd.to_datetime(df['date'])

# с форматом (быстрее)
df['date'] = pd.to_datetime(df['date'], format='%d.%m.%Y')

# с обработкой ошибок
df['date'] = pd.to_datetime(df['date'], errors='coerce')  # ошибки → NaT

При чтении CSV

df = pd.read_csv('data.csv', parse_dates=['date_col'])

# если нужен format
df = pd.read_csv(
    'data.csv',
    parse_dates=['date_col'],
    date_format='%d.%m.%Y'
)

dt accessor — извлечение частей

df['year']       = df['date'].dt.year
df['month']      = df['date'].dt.month
df['day']        = df['date'].dt.day
df['weekday']    = df['date'].dt.weekday   # 0 — понедельник
df['hour']       = df['date'].dt.hour
df['quarter']    = df['date'].dt.quarter
df['day_name']   = df['date'].dt.day_name()   # 'Monday'
df['month_name'] = df['date'].dt.month_name() # 'January'
df['is_weekend'] = df['date'].dt.weekday >= 5

Форматирование обратно в строку

df['date_str'] = df['date'].dt.strftime('%d.%m.%Y')
df['timestamp'] = df['date'].dt.strftime('%Y-%m-%d %H:%M:%S')

Арифметика с датами

# разница между двумя датами
df['days_diff'] = (df['end_date'] - df['start_date']).dt.days

# добавить / отнять дни
df['next_week'] = df['date'] + pd.Timedelta(days=7)
df['week_ago']  = df['date'] - pd.Timedelta(days=7)

# добавить месяцы (не точно, но часто нужно)
df['next_month'] = df['date'] + pd.DateOffset(months=1)

Группировка по датам

# по году
df.groupby(df['date'].dt.year)['amount'].sum()

# по месяцу (2026-04)
df.groupby(df['date'].dt.to_period('M'))['amount'].sum()

# по неделе
df.groupby(df['date'].dt.to_period('W'))['amount'].sum()

Resample — сгруппировать по времени

Нужен datetime в индексе:

df = df.set_index('date')

# суммы по дням
df.resample('D')['amount'].sum()

# по неделям
df.resample('W')['amount'].sum()

# по месяцам
df.resample('M')['amount'].sum()

Частоты: D (day), W, M, Q, Y, H, min, S.

Фильтр по датам

# после определённой
df[df['date'] > '2026-01-01']

# в диапазоне
df[(df['date'] >= '2026-01-01') & (df['date'] < '2026-05-01')]

# последние 7 дней
from datetime import datetime, timedelta
df[df['date'] >= datetime.now() - timedelta(days=7)]

pd.date_range — генерация дат

# 30 дней
dates = pd.date_range('2026-01-01', periods=30, freq='D')

# с шагом 15 минут
dates = pd.date_range('2026-01-01', periods=96, freq='15min')

# рабочие дни
dates = pd.date_range('2026-01-01', '2026-12-31', freq='B')

Таймзоны

# установить таймзону
df['date'] = df['date'].dt.tz_localize('UTC')

# конвертировать
df['date_msk'] = df['date'].dt.tz_convert('Europe/Moscow')

# убрать таймзону
df['date_naive'] = df['date'].dt.tz_localize(None)

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

# reindex чтобы все дни присутствовали
full_range = pd.date_range(df['date'].min(), df['date'].max(), freq='D')
df = df.set_index('date').reindex(full_range)
df['amount'] = df['amount'].fillna(0)  # дни без событий → 0

Rolling / moving average по времени

df = df.set_index('date').sort_index()

# скользящее среднее за 7 дней
df['ma7'] = df['amount'].rolling('7D').mean()

# скользящая сумма за 30 дней
df['sum30'] = df['amount'].rolling('30D').sum()

Первый/последний день периода

# начало месяца
df['month_start'] = df['date'].dt.to_period('M').dt.to_timestamp()

# конец месяца
df['month_end'] = df['date'] + pd.offsets.MonthEnd(0)

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

1. Сравнение строки с datetime

# иногда работает, но лучше cast
df[df['date_str'] > '2026-01-01']  # строковое сравнение

# правильно
df['date'] = pd.to_datetime(df['date_str'])
df[df['date'] > '2026-01-01']

2. Таймзоны и «свежесть»

UTC vs локальная — могут отличаться на день.

3. Забыть sort_index после set_index

Группировка / resample работают корректнее на отсортированных данных.

4. Медленный dt.year на миллионах строк

Если считаете на больших данных — лучше извлечь в колонку один раз, не каждый раз в запросе.

Связанные темы

FAQ

Как преобразовать Unix timestamp?

pd.to_datetime(df['ts'], unit='s') — из секунд. unit='ms' — миллисекунды.

dt.date или dt.strftime?

dt.date возвращает date-объект (не datetime). strftime — строку.

Период или timestamp?

Period (2026-04) — для группировок. Timestamp (2026-04-21 10:30) — для точных дат.

Resample или groupby?

Resample требует datetime index. Удобнее для временных рядов.


Тренируйте pandas — откройте тренажёр с 1500+ вопросами для собесов.