pandas: типы столбцов и очистка по правилу

Временные столбцы: парсинг, .dt-компоненты, длительности и фильтрация

Содержание курса

Фильтрация строк по временному интервалу через loc

Когда datetime-столбец готов, с ним можно строить булевы маски точно так же, как с числовыми столбцами: операторы >=, <=, >, < работают напрямую. Правая часть сравнения — строка в формате, который pandas понимает как дату, например '2024-02-01'.

import pandas as pd

df = pd.DataFrame({
    'event': ['A', 'B', 'C', 'D'],
    'start_str': ['2024-01-10 08:00', '2024-02-15 09:30', '2024-03-05 14:00', '2024-04-20 07:00'],
    'end_str':   ['2024-01-10 10:30', '2024-02-16 09:30', '2024-03-05 18:00', '2024-04-21 07:00']
})

df['start'] = pd.to_datetime(df['start_str'])
df['end']   = pd.to_datetime(df['end_str'])
df['duration'] = df['end'] - df['start']
df['hours'] = df['duration'].dt.total_seconds() / 3600

# Отбираем события, начавшиеся в феврале и марте 2024
mask = (df['start'] >= '2024-02-01') & (df['start'] < '2024-04-01')
result = df.loc[mask, ['event', 'start', 'hours']]
print(result)
  event               start  hours
1     B 2024-02-15 09:30:00   24.0
2     C 2024-03-05 14:00:00    4.0

События A и D не попали в выборку: A началось в январе, D — в апреле. Остались только B и C.

Про скобки. Каждое подусловие нужно оборачивать в скобки. Без них Python разбирает выражение не так, как вы ожидаете, и получается либо TypeError, либо неверный результат:

# Неверно — операторы сравнения и & имеют разные приоритеты
mask = df['start'] >= '2024-02-01' & df['start'] < '2024-04-01'

# Верно
mask = (df['start'] >= '2024-02-01') & (df['start'] < '2024-04-01')

Правило: если объединяете несколько условий через & или |, скобки обязательны вокруг каждого.

Вместо строки можно передать pd.Timestamp. Это тот же результат, просто более явный способ:

mask = (df['start'] >= pd.Timestamp('2024-02-01')) & (df['start'] < pd.Timestamp('2024-04-01'))

Поведение идентично — pandas всё равно приводит строки к Timestamp внутри сравнения. Разница чисто стилистическая.

Полный пайплайн. Всё, что разбиралось в этом уроке, ложится в одну последовательность:

  1. pd.to_datetime превращает строки в datetime64[ns].
  2. .dt.year, .dt.month, .dt.dayofweek, .dt.hour — числовые признаки из даты.
  3. Вычитание двух datetime-столбцов даёт timedelta64[ns]; total_seconds() или деление на pd.Timedelta переводит в числа.
  4. Булева маска с >= и < на datetime-столбце + df.loc[mask] отбирает нужный временной интервал.

Каждый шаг независим: можно извлечь .dt.month без вычисления длительности, или отфильтровать строки без создания новых компонентных столбцов. Но вместе они покрывают большинство задач, которые возникают при работе с временными данными.

Эти же числовые столбцы — month, dayofweek, hour — станут естественными ключами группировки, когда дойдёте до groupby.