Модуль 3: Робота з таблицями та фільтрація даних

УРОК 3

Час60-90 хвилин
ПотрібноУроки 1-2, встановлений pip
РезультатСкрипти для аналізу табличних даних

Задача

Дані часто приходять у таблицях: Excel-файли від штабу, CSV-експорти з систем, логи у табличному форматі. Типові задачі:

В Excel це робиться вручну: фільтри, ВПР, зведені таблиці. Python робить те саме, але автоматично і з будь-яким обсягом даних — хоч 100 рядків, хоч 100 000.

Що освоїмо

Нові терміни

PandasБібліотека Python для роботи з таблицями. Назва від "Panel Data". Це як Excel, але в коді.
DataFrameТаблиця в Pandas. Має рядки, колонки, заголовки. Основна структура для роботи з даними.
ФільтраціяВибір рядків, що відповідають умові. Як фільтр в Excel, тільки гнучкіше.
АгрегаціяОбчислення на групах даних: сума, середнє, кількість. Як зведена таблиця в Excel.
pipМенеджер пакетів Python. Команда для встановлення бібліотек з інтернету.

Встановлення Pandas

Pandas — зовнішня бібліотека, її треба встановити окремо. Це робиться один раз.

Відкрий термінал і введи:

pip install pandas openpyxl

На Linux може знадобитися:

pip3 install pandas openpyxl
💡 openpyxl — бібліотека для читання Excel-файлів (.xlsx). Pandas використовує її "під капотом". Встановлюємо разом, щоб потім не було помилок.

Перевірка встановлення:

python -c "import pandas; print(pandas.__version__)"

Якщо бачиш номер версії (наприклад, 2.1.4) — все працює.

Вхідні дані

Для цього уроку використаємо CSV-файл (простіше створити вручну). У реальній роботі Pandas так само читає Excel.

Створи файл events.csv у папці C:\osint:

date,time,event_type,sector,lat,lon,source 2025-01-15,08:23,movement,A,48.4567,35.0234,radio 2025-01-15,08:45,contact,B,48.5123,35.1456,visual 2025-01-15,09:12,movement,A,48.4601,35.0301,radio 2025-01-15,09:30,fire,C,49.1234,36.5678,radar 2025-01-15,10:15,movement,B,48.5200,35.1500,radio 2025-01-15,10:45,contact,A,48.4700,35.0400,visual 2025-01-15,11:00,movement,C,49.1300,36.5700,radio 2025-01-15,11:30,fire,A,48.4800,35.0500,radar 2025-01-15,12:00,contact,B,48.5300,35.1600,visual 2025-01-15,14:30,movement,A,48.4900,35.0600,radio 2025-01-15,15:00,fire,B,48.5400,35.1700,radar 2025-01-15,16:20,contact,C,49.1400,36.5800,visual
⚠ CSV-файл — це звичайний текст із комами як роздільниками. Зберігай у VS Code, не в Excel (Excel може змінити формат). Кодування — UTF-8.

Скрипт: базові операції

Створи файл analyze_events.py:

# Аналіз табличних даних з Pandas # Демонструє: читання, фільтрацію, групування, збереження import pandas as pd # pd — стандартне скорочення для pandas # -------- ЧИТАННЯ ДАНИХ -------- # Завантажуємо CSV у DataFrame (таблицю) df = pd.read_csv('events.csv') # Показуємо перші 5 рядків — щоб переконатися, що дані прочиталися print("=== ПЕРШІ 5 РЯДКІВ ===") print(df.head()) print() # Базова інформація про таблицю print("=== ІНФОРМАЦІЯ ПРО ДАНІ ===") print(f"Рядків: {len(df)}") print(f"Колонки: {list(df.columns)}") print() # -------- ФІЛЬТРАЦІЯ -------- # Вибираємо тільки події типу "fire" fires = df[df['event_type'] == 'fire'] print("=== ПОДІЇ ТИПУ 'FIRE' ===") print(fires) print() # Вибираємо події в секторі A після 10:00 # Спочатку фільтр по сектору, потім по часу sector_a = df[df['sector'] == 'A'] sector_a_after_10 = sector_a[sector_a['time'] > '10:00'] print("=== СЕКТОР A ПІСЛЯ 10:00 ===") print(sector_a_after_10) print() # Комбінований фільтр (те саме, але в один рядок) # & означає "І", | означає "АБО" combined = df[(df['sector'] == 'A') & (df['time'] > '10:00')] print("=== ТОЙ САМИЙ РЕЗУЛЬТАТ (КОМБІНОВАНИЙ ФІЛЬТР) ===") print(combined) print() # -------- ГРУПУВАННЯ ТА ПІДРАХУНОК -------- # Скільки подій кожного типу? by_type = df.groupby('event_type').size() print("=== КІЛЬКІСТЬ ПО ТИПАХ ===") print(by_type) print() # Скільки подій у кожному секторі? by_sector = df.groupby('sector').size() print("=== КІЛЬКІСТЬ ПО СЕКТОРАХ ===") print(by_sector) print() # Перехресна таблиця: типи подій по секторах cross = pd.crosstab(df['sector'], df['event_type']) print("=== ТИПИ ПОДІЙ ПО СЕКТОРАХ ===") print(cross) print() # -------- ЗБЕРЕЖЕННЯ РЕЗУЛЬТАТІВ -------- # Зберігаємо відфільтровані дані в новий файл fires.to_csv('fires_only.csv', index=False) print("Файл fires_only.csv збережено") # Зберігаємо статистику by_sector.to_csv('stats_by_sector.csv') print("Файл stats_by_sector.csv збережено")

Запуск

cd C:\osint python analyze_events.py

Очікуваний результат

=== ПЕРШІ 5 РЯДКІВ === date time event_type sector lat lon source 0 2025-01-15 08:23 movement A 48.4567 35.0234 radio 1 2025-01-15 08:45 contact B 48.5123 35.1456 visual 2 2025-01-15 09:12 movement A 48.4601 35.0301 radio 3 2025-01-15 09:30 fire C 49.1234 36.5678 radar 4 2025-01-15 10:15 movement B 48.5200 35.1500 radio === ІНФОРМАЦІЯ ПРО ДАНІ === Рядків: 12 Колонки: ['date', 'time', 'event_type', 'sector', 'lat', 'lon', 'source'] === ПОДІЇ ТИПУ 'FIRE' === date time event_type sector lat lon source 3 2025-01-15 09:30 fire C 49.1234 36.5678 radar 7 2025-01-15 11:30 fire A 48.4800 35.0500 radar 10 2025-01-15 15:00 fire B 48.5400 35.1700 radar === СЕКТОР A ПІСЛЯ 10:00 === date time event_type sector lat lon source 5 2025-01-15 10:45 contact A 48.470 35.040 visual 7 2025-01-15 11:30 fire A 48.480 35.050 radar 9 2025-01-15 14:30 movement A 48.490 35.060 radio === КІЛЬКІСТЬ ПО ТИПАХ === event_type contact 3 fire 3 movement 6 dtype: int64 === КІЛЬКІСТЬ ПО СЕКТОРАХ === sector A 5 B 4 C 3 dtype: int64 === ТИПИ ПОДІЙ ПО СЕКТОРАХ === event_type contact fire movement sector A 1 1 3 B 2 1 1 C 1 1 1 Файл fires_only.csv збережено Файл stats_by_sector.csv збережено

Ключові концепції

DataFrame — це таблиця

df = pd.read_csv('file.csv')

df — змінна, яка містить таблицю. Можна назвати як завгодно, але df — стандартна назва (від DataFrame).

Доступ до колонок

df['sector'] # Одна колонка df[['sector', 'time']] # Кілька колонок

Квадратні дужки з назвою колонки. Для кількох колонок — список у подвійних дужках.

Фільтрація

df[df['sector'] == 'A'] # Рядки, де сектор = A df[df['time'] > '10:00'] # Рядки, де час > 10:00 df[df['lat'] > 48.5] # Рядки, де широта > 48.5

Умова в дужках створює маску (True/False для кожного рядка). Pandas залишає тільки рядки з True.

==Дорівнює
!=Не дорівнює
> <Більше / менше
>= <=Більше-рівне / менше-рівне
&І (обидві умови)
|АБО (хоча б одна)

Групування

df.groupby('sector').size() # Кількість по секторах df.groupby('sector')['lat'].mean() # Середня широта по секторах

groupby розбиває таблицю на групи. Потім до кожної групи застосовуємо функцію: size() — кількість, mean() — середнє, sum() — сума.

Збереження

df.to_csv('output.csv', index=False) # Без номерів рядків df.to_excel('output.xlsx', index=False) # В Excel

index=False прибирає колонку з номерами рядків, яку Pandas додає автоматично.

Читання Excel-файлів

Якщо дані в Excel замість CSV:

# Читання Excel df = pd.read_excel('data.xlsx') # Читання конкретного аркуша df = pd.read_excel('data.xlsx', sheet_name='Sheet2') # Читання всіх аркушів (повертає словник) all_sheets = pd.read_excel('data.xlsx', sheet_name=None) for sheet_name, sheet_df in all_sheets.items(): print(f"Аркуш: {sheet_name}, рядків: {len(sheet_df)}")

Практична задача: об'єднання файлів

Часта ситуація: дані за різні дні в окремих файлах. Треба об'єднати в один.

Створи файл events_day2.csv:

date,time,event_type,sector,lat,lon,source 2025-01-16,07:00,movement,B,48.5100,35.1400,radio 2025-01-16,08:30,fire,A,48.4650,35.0350,radar 2025-01-16,09:45,contact,C,49.1250,36.5650,visual

Скрипт для об'єднання (merge_files.py):

import pandas as pd # Читаємо обидва файли df1 = pd.read_csv('events.csv') df2 = pd.read_csv('events_day2.csv') print(f"Файл 1: {len(df1)} рядків") print(f"Файл 2: {len(df2)} рядків") # Об'єднуємо вертикально (додаємо рядки знизу) combined = pd.concat([df1, df2], ignore_index=True) print(f"Об'єднано: {len(combined)} рядків") # Сортуємо по даті та часу combined = combined.sort_values(['date', 'time']) # Зберігаємо combined.to_csv('all_events.csv', index=False) print("Збережено у all_events.csv")
💡 pd.concat() об'єднує таблиці. ignore_index=True перенумеровує рядки з нуля. sort_values() сортує — можна по кількох колонках.

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

ПомилкаРішення
ModuleNotFoundError: No module named 'pandas'Pandas не встановлено. Виконай: pip install pandas
ModuleNotFoundError: No module named 'openpyxl'Для Excel потрібен openpyxl: pip install openpyxl
FileNotFoundErrorФайл не знайдено. Перевір назву та папку.
ParserError: Error tokenizing dataПроблема з форматом CSV. Перевір, що коми — роздільники, немає зайвих ком.
KeyError: 'column_name'Такої колонки немає. Перевір df.columns — які колонки є насправді.
UnicodeDecodeErrorПроблема з кодуванням. Спробуй: pd.read_csv('file.csv', encoding='cp1251')

Робота з AI

Типові промпти

У мене CSV-файл events.csv з колонками: date, time, event_type, sector, lat, lon, source. Напиши Python-скрипт з pandas, який: 1. Читає файл 2. Фільтрує події типу "fire" у секторах A та B 3. Групує по датах і рахує кількість 4. Зберігає результат у fires_summary.csv Додай коментарі українською.

Складніший запит

Є два Excel-файли: - positions.xlsx: колонки unit_id, lat, lon, timestamp - intel.xlsx: колонки unit_id, unit_type, status Напиши скрипт, який: 1. Об'єднує файли по unit_id (як ВПР в Excel) 2. Залишає тільки unit_type = "armor" 3. Рахує кількість по status 4. Зберігає у звіт

Типові помилки AI

Чек-лист

☐ Pandas встановлено (pip install pandas openpyxl) ☐ Файл events.csv створено ☐ analyze_events.py запускається без помилок ☐ Виводиться статистика по типах і секторах ☐ Створено файли fires_only.csv та stats_by_sector.csv ☐ Файл events_day2.csv створено ☐ merge_files.py об'єднує файли в all_events.csv

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

Шпаргалка Pandas

КомандаОпис
pd.read_csv('file.csv')Читання CSV
pd.read_excel('file.xlsx')Читання Excel
df.head()Перші 5 рядків
df.columnsСписок колонок
len(df)Кількість рядків
df['col']Одна колонка
df[df['col'] == 'value']Фільтр по значенню
df.groupby('col').size()Групування + підрахунок
pd.concat([df1, df2])Об'єднання таблиць
df.to_csv('out.csv', index=False)Збереження в CSV

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

Урок 4: Збір даних з відкритих джерел

HTTP-запити, парсинг сайтів, робота з API — автоматизований OSINT.