# Летняя практика — Турнирные таблицы КХЛ Проект анализирует результаты матчей регулярного чемпионата КХЛ за сезоны **2018/19 – 2021/22** и строит по ним турнирные таблицы и графики. Основной инструмент — библиотека **pandas** (работа с таблицами) и **matplotlib** (графики). --- ## 1. Структура проекта | Файл / папка | Назначение | |---|---| | `main.py` | Основная программа: строит полную турнирную таблицу чемпионата и таблицы по конференциям (Запад / Восток). | | `individual_1.py` | Индивидуальное задание: гистограмма набранных очков по командам. | | `individual_4.py` | Индивидуальное задание: гистограмма всего заброшенных шайб за сезон. | | `individual_5.py` | Индивидуальное задание: гистограмма разницы шайб конкретной команды в заданном периоде по датам. | | `khl_3/` | Исходные данные — CSV-файлы матчей (кодировка UTF-8). | | `khl_3_win/` | Те же данные в кодировке UTF-8 **с BOM** — открываются в Excel без «кракозябр». | ### Формат исходных данных (CSV) ``` ,Номер,Дата,Команда_1,Команда_2,Период_1,Период_2,Период_3,Овертайм,Буллиты 0,1,2018-09-01,Ак Барс,СКА,0:1,1:2,0:3,:,: ``` * `Команда_1` — хозяева, `Команда_2` — гости. * `Период_1..3`, `Овертайм`, `Буллиты` — счёт в формате `хозяева:гости`. * Пустой `:` означает, что период не игрался (нет овертайма/буллитов). --- ## 2. Установка и запуск ```bash pip install pandas numpy matplotlib # Полная турнирная таблица + таблицы по конференциям python3 main.py khl_3/khl_2018_19.csv # Гистограмма очков (по желанию — сохранить в файл) python3 individual_1.py khl_3/khl_2018_19.csv [output.png] # Гистограмма заброшенных шайб python3 individual_4.py khl_3/khl_2018_19.csv # Разница шайб команды в N-м периоде по датам python3 individual_5.py khl_3/khl_2018_19.csv 2 "Ак Барс" [output.png] ``` > Имя файла важно: `main.py` достаёт код сезона (`2018_19`) из имени `khl_2018_19.csv`, > чтобы понять, какие команды в какой конференции играли. --- ## 3. Как работает `main.py` (ядро проекта) Логика построена на **векторных операциях pandas**: вычисления делаются сразу над целым столбцом, без циклов по строкам. **Шаг 1. `parse_score(df, col)`** — разбирает строку счёта `"3:1"` на два числа. `str.split(':', expand=True)` раскладывает столбец в два, `to_numeric(..., errors='coerce')` превращает текст в числа, а пустой период (`:`) через `fillna(0)` считается как `0:0`. **Шаг 2. `build_standings(df, conf_map)`** — превращает список матчей в таблицу команд: 1. Считает голы в основное время (сумма трёх периодов). 2. Определяет **тип исхода** каждого матча сравнением столбцов: победа в основное время / в овертайме / по буллитам — и аналогично поражения. Победителю по буллитам добавляется ровно 1 решающая шайба. 3. **«Разворачивает» матч в две строки** — взгляд хозяев и взгляд гостей — и склеивает их (`pd.concat`). Теперь у каждой команды по строке на матч. 4. `groupby('Команда').sum()` суммирует все показатели по командам. 5. Считает производные показатели: * **И** — игры, **О** — очки (победа = 2, поражение в ОТ/буллитах = 1), * **Р** — разница шайб, **%О** — процент набранных очков. * `%О` считается с **отбрасыванием** знаков (`np.floor`), как на сайте КХЛ, а не округлением. 6. Сортирует по регламенту КХЛ: `%О → В → ВО → ВБ → Р → ГЗ`. **Шаг 3. `show_table` и `main`** — печатают полную таблицу, затем отдельно конференции Запад и Восток (фильтр по столбцу `Конф`). ### Обозначения столбцов `И` — игры · `В` — победы в основное время · `ВО` — победы в овертайме · `ВБ` — победы по буллитам · `ПБ` — поражения по буллитам · `ПО` — поражения в овертайме · `П` — поражения в основное время · `ГЗ` — голы забитые · `ГП` — голы пропущенные · `Р` — разница · `О` — очки · `%О` — процент очков. --- ## 4. Индивидуальные задания * **`individual_1.py`** — переиспользует `parse_score` из `main.py`, считает очки каждой команды и строит **столбчатую диаграмму очков**. Поддерживает сохранение в PNG. * **`individual_4.py`** — суммирует все заброшенные шайбы каждой команды за сезон и строит гистограмму с подписями значений над столбцами. * **`individual_5.py`** — фильтрует матчи одной команды, считает **разницу шайб в выбранном периоде** по датам. Столбцы раскрашены: зелёный (плюс), красный (минус), серый (ноль); добавлена линия нуля и сетка. --- ## 5. Материал к защите **О чём проект.** По «сырым» результатам матчей КХЛ автоматически строится официальная турнирная таблица и набор графиков. Цель — освоить обработку табличных данных в pandas и визуализацию в matplotlib. **Ключевые идеи, которые стоит назвать на защите:** 1. **Векторизация вместо циклов.** Все расчёты — операции над столбцами целиком (сложение, сравнение, маски `True/False`). Это и быстрее, и короче, чем `for` по строкам. 2. **Приём «одна строка матча → две строки команд».** Чтобы посчитать статистику команды, каждый матч дублируется: одна запись со стороны хозяев, другая — гостей. После этого `groupby` сводит всё в таблицу команд. 3. **Булевы маски.** Тип исхода (победа/поражение и как именно) — это столбцы `True/False`, которые переводятся в `1/0` через `.astype(int)` и суммируются. 4. **Точное соответствие регламенту КХЛ.** Система очков (2/1/0), добавление шайбы за буллиты, отбрасывание (а не округление) процента очков, порядок критериев сортировки. 5. **Переиспользование кода.** `individual_1.py` импортирует функции из `main.py`, чтобы не дублировать логику разбора счёта. **Возможные вопросы и ответы:** * *Почему пустой период = 0:0?* — Овертайм/буллиты есть не во всех матчах; `fillna(0)` делает расчёт единообразным. * *Почему `np.floor`, а не `round`?* — Сайт КХЛ отбрасывает знаки после второго (72.448 → 72.44), а не округляет. * *Зачем папка `khl_3_win`?* — то же содержимое, но с BOM, чтобы Excel правильно показывал кириллицу. * *Как добавить новый сезон?* — добавить CSV в `khl_3/` и описать конференции в словаре `CONFERENCES` внутри `main.py`.