Модуль 6: Аналіз часових патернів

УРОК 6

Час60-90 хвилин
ПотрібноУроки 1-5, events.csv
РезультатАналіз та графіки часових патернів

Задача

Час — критичний параметр в аналізі. Типові питання:

Нові терміни

datetimeТип даних Python для дати та часу. Дозволяє арифметику: різниця, додавання.
timestampМітка часу — момент у часі. Може бути числом (секунди від 1970) або рядком.
timedeltaРізниця між двома моментами. "3 дні 4 години" — це timedelta.
resampleАгрегація по часових інтервалах: по годинах, днях, тижнях.
rollingКовзне вікно — середнє/сума за останні N періодів.

Частина 1: Робота з датами

Базові операції

from datetime import datetime, timedelta # Поточний час now = datetime.now() print(f"Зараз: {now}") # Створення дати з рядка date_str = "2025-01-15 08:23:00" dt = datetime.strptime(date_str, "%Y-%m-%d %H:%M:%S") print(f"Розпарсено: {dt}") # Витягування компонентів print(f"Рік: {dt.year}") print(f"Місяць: {dt.month}") print(f"День: {dt.day}") print(f"Година: {dt.hour}") print(f"День тижня: {dt.weekday()}") # 0 = понеділок # Форматування назад у рядок formatted = dt.strftime("%d.%m.%Y %H:%M") print(f"Форматовано: {formatted}")

Формати дати

%YРік (4 цифри): 2025
%mМісяць (01-12): 01
%dДень (01-31): 15
%HГодина (00-23): 08
%MХвилина (00-59): 23
%SСекунда (00-59): 00
%AДень тижня: Monday
%BМісяць словом: January

Арифметика з часом

from datetime import datetime, timedelta dt1 = datetime(2025, 1, 15, 8, 0) dt2 = datetime(2025, 1, 15, 14, 30) # Різниця diff = dt2 - dt1 print(f"Різниця: {diff}") # 6:30:00 print(f"Секунд: {diff.total_seconds()}") # 23400.0 print(f"Годин: {diff.total_seconds() / 3600}") # 6.5 # Додавання tomorrow = dt1 + timedelta(days=1) two_hours_later = dt1 + timedelta(hours=2) print(f"Завтра: {tomorrow}") print(f"+2 години: {two_hours_later}")

Частина 2: Дати в Pandas

Pandas має потужні інструменти для часових рядів:

import pandas as pd # Створюємо тестові дані data = { 'timestamp': [ '2025-01-15 08:23', '2025-01-15 08:45', '2025-01-15 09:12', '2025-01-15 14:30', '2025-01-15 15:00', '2025-01-15 16:20', '2025-01-16 07:00', '2025-01-16 08:30', '2025-01-16 09:45', '2025-01-17 10:00', '2025-01-17 11:15', '2025-01-17 14:00' ], 'event_type': ['movement', 'fire', 'contact'] * 4, 'sector': ['A', 'B', 'C'] * 4 } df = pd.DataFrame(data) # Конвертуємо в datetime df['timestamp'] = pd.to_datetime(df['timestamp']) # Витягуємо компоненти df['date'] = df['timestamp'].dt.date df['hour'] = df['timestamp'].dt.hour df['day_of_week'] = df['timestamp'].dt.dayofweek # 0 = понеділок df['day_name'] = df['timestamp'].dt.day_name() print(df[['timestamp', 'hour', 'day_name']].head())

Корисні .dt аксесори

.dt.yearРік
.dt.monthМісяць (1-12)
.dt.dayДень місяця
.dt.hourГодина
.dt.minuteХвилина
.dt.dayofweekДень тижня (0-6)
.dt.day_name()Назва дня
.dt.dateТільки дата
.dt.timeТільки час

Частина 3: Аналіз патернів

Розподіл по годинах

# Скільки подій кожної години? hourly = df.groupby('hour').size() print("Активність по годинах:") print(hourly) # Пікова година peak_hour = hourly.idxmax() print(f"\nПікова година: {peak_hour}:00 ({hourly[peak_hour]} подій)")

Розподіл по днях тижня

# Дні тижня українською day_names = {0: 'Пн', 1: 'Вт', 2: 'Ср', 3: 'Чт', 4: 'Пт', 5: 'Сб', 6: 'Нд'} by_day = df.groupby('day_of_week').size() by_day.index = by_day.index.map(day_names) print("Активність по днях тижня:") print(by_day)

Інтервали між подіями

# Сортуємо по часу df_sorted = df.sort_values('timestamp') # Різниця з попередньою подією df_sorted['time_since_prev'] = df_sorted['timestamp'].diff() print("Інтервали між подіями:") print(df_sorted[['timestamp', 'time_since_prev']].head(10)) # Статистика інтервалів intervals = df_sorted['time_since_prev'].dropna() print(f"\nСередній інтервал: {intervals.mean()}") print(f"Мінімальний: {intervals.min()}") print(f"Максимальний: {intervals.max()}")

Частина 4: Візуалізація

matplotlib — стандартна бібліотека для графіків:

pip install matplotlib

Графік активності по годинах

import matplotlib.pyplot as plt # Дані hourly = df.groupby('hour').size() # Графік plt.figure(figsize=(10, 5)) plt.bar(hourly.index, hourly.values, color='steelblue') plt.xlabel('Година') plt.ylabel('Кількість подій') plt.title('Розподіл активності по годинах') plt.xticks(range(0, 24)) plt.grid(axis='y', alpha=0.3) plt.savefig('hourly_activity.png', dpi=150) plt.close() print("Графік збережено: hourly_activity.png")

Теплова карта: години × дні

import numpy as np # Створюємо матрицю: рядки = дні, колонки = години pivot = df.groupby(['day_of_week', 'hour']).size().unstack(fill_value=0) plt.figure(figsize=(12, 4)) plt.imshow(pivot.values, cmap='YlOrRd', aspect='auto') plt.colorbar(label='Кількість подій') plt.xlabel('Година') plt.ylabel('День тижня') plt.yticks(range(7), ['Пн', 'Вт', 'Ср', 'Чт', 'Пт', 'Сб', 'Нд']) plt.xticks(range(24)) plt.title('Теплова карта активності') plt.savefig('heatmap.png', dpi=150) plt.close() print("Теплова карта збережено: heatmap.png")

Частина 5: Виявлення патернів

Регулярність подій

# Чи є події в один і той самий час? df['time_slot'] = df['timestamp'].dt.strftime('%H:%M') # Які часові слоти повторюються? recurring = df.groupby('time_slot').size() recurring = recurring[recurring > 1].sort_values(ascending=False) if len(recurring) > 0: print("Повторювані часові слоти:") print(recurring) else: print("Регулярних патернів не виявлено")

Аномальні інтервали

# Знаходимо незвично короткі або довгі інтервали intervals = df_sorted['time_since_prev'].dropna() # Порогові значення (можна налаштувати) mean_interval = intervals.mean() std_interval = intervals.std() # Аномально короткі (< mean - 2*std) short_threshold = mean_interval - 2 * std_interval # Аномально довгі (> mean + 2*std) long_threshold = mean_interval + 2 * std_interval anomalies = df_sorted[ (df_sorted['time_since_prev'] < short_threshold) | (df_sorted['time_since_prev'] > long_threshold) ] print(f"Середній інтервал: {mean_interval}") print(f"Аномально коротких: {len(anomalies[anomalies['time_since_prev'] < short_threshold])}") print(f"Аномально довгих: {len(anomalies[anomalies['time_since_prev'] > long_threshold])}")

Практична задача

Повний аналіз часових патернів. Створи time_analysis.py:

import pandas as pd import matplotlib.pyplot as plt from datetime import datetime # --- ЗАВАНТАЖЕННЯ --- df = pd.read_csv('events.csv') df['datetime'] = pd.to_datetime(df['date'] + ' ' + df['time']) df['hour'] = df['datetime'].dt.hour print(f"Період: {df['datetime'].min()} — {df['datetime'].max()}") print(f"Усього подій: {len(df)}") # --- АНАЛІЗ ПО ГОДИНАХ --- hourly = df.groupby('hour').size() print(f"\nПікова година: {hourly.idxmax()}:00") print(f"Найменша активність: {hourly.idxmin()}:00") # --- АНАЛІЗ ПО ТИПАХ --- print("\nПодії по типах та годинах:") pivot = df.pivot_table(index='hour', columns='event_type', aggfunc='size', fill_value=0) print(pivot) # --- ІНТЕРВАЛИ --- df_sorted = df.sort_values('datetime') df_sorted['interval'] = df_sorted['datetime'].diff() mean_int = df_sorted['interval'].mean() print(f"\nСередній інтервал: {mean_int}") # --- ГРАФІК --- fig, axes = plt.subplots(1, 2, figsize=(14, 5)) # Гістограма по годинах axes[0].bar(hourly.index, hourly.values, color='steelblue') axes[0].set_xlabel('Година') axes[0].set_ylabel('Кількість') axes[0].set_title('Активність по годинах') axes[0].set_xticks(range(0, 24, 2)) # Типи подій по годинах pivot.plot(kind='bar', stacked=True, ax=axes[1], colormap='Set2') axes[1].set_xlabel('Година') axes[1].set_ylabel('Кількість') axes[1].set_title('Типи подій по годинах') axes[1].legend(title='Тип') plt.tight_layout() plt.savefig('time_analysis.png', dpi=150) print("\nГрафіки збережено: time_analysis.png")

Якщо не працює

ПомилкаРішення
ValueError: time data does not match formatФормат дати не співпадає. Перевір strptime формат.
TypeError: unsupported operand for -Один з операндів не datetime. Конвертуй через pd.to_datetime()
OutOfBoundsDatetimeДата поза допустимим діапазоном (1677-2262). Перевір дані.
No module named 'matplotlib'pip install matplotlib

Робота з AI

Є CSV з колонками: timestamp (формат YYYY-MM-DD HH:MM:SS), event_type, sector. Напиши скрипт для аналізу часових патернів: 1. Розподіл подій по годинах та днях тижня 2. Теплова карта (години × дні) 3. Виявлення регулярних патернів (події в один час) 4. Пошук аномальних інтервалів (> 2 std від середнього) 5. Звіт у текстовий файл + графіки PNG Українські підписи на графіках.

Чек-лист

☐ matplotlib встановлено ☐ Дати конвертуються в datetime ☐ Аналіз по годинах працює ☐ Інтервали розраховуються ☐ Графіки зберігаються в PNG

Самостійна практика

Наступний урок

Урок 7: Текстовий аналіз та NLP

Аналіз тексту повідомлень, пошук ключових слів, класифікація.