No description
Find a file
2026-06-30 11:59:17 +03:00
khl_3 swag 2026-06-25 19:16:00 +03:00
khl_3_win Add individual_5.py and Excel-compatible CSV files (khl_3_win) 2026-06-28 18:35:47 +03:00
.gitignore Initial commit 2026-06-25 16:04:24 +00:00
3.py fix main.py and add divisions.py 2026-06-30 09:23:39 +03:00
individual_1.py Индивидуальное задание 1 2026-06-28 14:24:23 +03:00
individual_4.py Индивидуальное задание 4 2026-06-28 19:02:08 +03:00
individual_5.py Add individual_5.py and Excel-compatible CSV files (khl_3_win) 2026-06-28 18:35:47 +03:00
main.py new_main.py теперь основной 2026-06-30 10:49:28 +03:00
new_main.py new_main.py теперь основной 2026-06-30 10:49:28 +03:00
README.md update doc 2026-06-30 09:54:59 +03:00
РАЗБОР_КОДА.md update doc 2026-06-30 09:54:59 +03:00

Летняя практика — Турнирные таблицы КХЛ

Проект анализирует результаты матчей регулярного чемпионата КХЛ за сезоны 2018/19 2021/22 и строит по ним турнирные таблицы и график. Основные инструменты — библиотека pandas (работа с таблицами) и matplotlib (график).


1. Структура проекта

Файл / папка Назначение
main.py Основная программа: строит полную турнирную таблицу чемпионата и таблицы по конференциям (Запад / Восток).
divisions.py Отдельный модуль: добавляет деление на дивизионы и правило посева победителей дивизионов. Логику расчёта берёт из main.py, сам main.py не меняет.
3.py Задание №3: график разницы заброшенных и пропущенных шайб одной команды по ходу сезона.
khl_3/ Исходные данные — CSV-файлы матчей (4 сезона, кодировка UTF-8).

Формат исходных данных (CSV)

,Номер,Дата,Команда_1,Команда_2,Период_1,Период_2,Период_3,Овертайм,Буллиты
0,1,2018-09-01,Ак Барс,СКА,0:1,1:2,0:3,:,:
  • Команда_1 — хозяева, Команда_2 — гости.
  • Период_1..3, Овертайм, Буллиты — счёт в формате хозяева:гости.
  • Пустой : означает, что период не игрался (нет овертайма/буллитов).
  • Технические результаты записаны знаками: + — - (техпобеда хозяев) и - — + (техпобеда гостей). Встречаются в сезоне 2020/21.

2. Установка и запуск

pip install pandas numpy matplotlib

# Полная турнирная таблица + таблицы по конференциям
python3 main.py khl_3/khl_2018_19.csv

# Таблицы по конференциям с дивизионами и посевом победителей дивизионов
python3 divisions.py khl_3/khl_2020_21.csv

# График разницы шайб одной команды по датам (сохраняется в diff_<команда>.png)
python3 3.py khl_3/khl_2018_19.csv "ЦСКА"

Имя файла важно: программы достают код сезона (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.

Шаг 2. build_standings(df, conf_map) — превращает список матчей в таблицу команд:

  1. Считает голы в основное время (сумма трёх периодов).
  2. Определяет тип исхода каждого матча сравнением столбцов: победа в основное время / в овертайме / по буллитам — и аналогично поражения. Победителю по буллитам добавляется ровно 1 решающая шайба.
  3. Отдельно обрабатывает технические результаты (+ — - / - — +): засчитывает их как победу/поражение в основное время, но шайбы не начисляет (0:0).
  4. «Разворачивает» матч в две строки — взгляд хозяев и взгляд гостей — и склеивает их (pd.concat). Теперь у каждой команды по строке на матч.
  5. groupby('Команда').sum() суммирует все показатели по командам.
  6. Считает производные показатели:
    • И — игры, О — очки (победа = 2, поражение в ОТ/буллитах = 1),
    • Р — разница шайб, %О — процент набранных очков.
    • %О считается в целых числах (* 10000 // (2*И) / 100) с отбрасыванием знаков, как на сайте КХЛ, — без округления и без ошибок float (57.00 не съезжает в 56.99).
  7. Сортирует по регламенту КХЛ: %ОВВО → ВБ → Р → ГЗ.

Шаг 3. show_table и main — печатают полную таблицу, затем отдельно конференции Запад и Восток (фильтр по столбцу Конф).

Обозначения столбцов

И — игры · В — победы в основное время · ВО — победы в овертайме · ВБ — победы по буллитам · ПБ — поражения по буллитам · ПО — поражения в овертайме · П — поражения в основное время · ГЗ — голы забитые · ГП — голы пропущенные · Р — разница · О — очки · %О — процент очков.


4. Дополнительные файлы

divisions.py — дивизионы и посев

В части сезонов КХЛ (2018/192020/21) действовало правило: победители двух дивизионов получают места 1 и 2 в конференции, даже если по очкам они не в топ-2. Например, в 2020/21 на Западе СКА (82 очка) стоит выше Динамо М (84) и Локомотива (83) — СКА выиграл дивизион Боброва. В сезоне 2021/22 это правило отменили (чистый порядок по %О).

divisions.py:

  • переиспользует build_standings и CONFERENCES из main.py (не дублируя логику и не изменяя main.py);
  • словарь DIVISIONS задаёт состав четырёх дивизионов (Боброва, Тарасова — Запад; Харламова, Чернышёва — Восток) по каждому сезону;
  • SEED_BY_DIVISION включает посев только там, где он применялся;
  • seed_conference поднимает победителей дивизионов на места 12;
  • выводит таблицы конференций с дополнительным столбцом Див.

3.py — график разницы шайб

Задание №3: строит график разницы заброшенных и пропущенных шайб одной команды по датам матчей. Считает голы в каждом матче (match_goals, та же логика подсчёта, что в main.py, включая зануление технических результатов), разносит матч на взгляд хозяев и гостей, оставляет нужную команду, рисует линию «забито пропущено» по дате и сохраняет картинку diff_<команда>.png.


5. Материал к защите

О чём проект. По «сырым» результатам матчей КХЛ автоматически строится официальная турнирная таблица, таблицы с дивизионами и график. Цель — освоить обработку табличных данных в pandas и визуализацию в matplotlib.

Ключевые идеи, которые стоит назвать на защите:

  1. Векторизация вместо циклов. Все расчёты — операции над столбцами целиком (сложение, сравнение, маски True/False). Это и быстрее, и короче, чем for по строкам.
  2. Приём «одна строка матча → две строки команд». Чтобы посчитать статистику команды, каждый матч дублируется: одна запись со стороны хозяев, другая — гостей. После этого groupby сводит всё в таблицу команд.
  3. Булевы маски. Тип исхода (победа/поражение и как именно) — это столбцы True/False, которые переводятся в 1/0 через .astype(int) и суммируются.
  4. Точное соответствие регламенту КХЛ. Система очков (2/1/0), добавление шайбы за буллиты, технические результаты, целочисленный (без округления) процент очков, порядок критериев сортировки, посев победителей дивизионов.
  5. Переиспользование кода. divisions.py и 3.py опираются на логику из main.py, чтобы не дублировать разбор счёта и расчёт таблицы.

Возможные вопросы и ответы:

  • Почему пустой период = 0:0? — Овертайм/буллиты есть не во всех матчах; fillna(0) делает расчёт единообразным.
  • Почему %О считается в целых числах, а не через round? — Сайт КХЛ отбрасывает знаки после второго (а не округляет), и целочисленная арифметика не даёт ошибок float (57.00 вместо 56.99...).
  • Как обрабатываются технические результаты?+ — - / - — + засчитываются как победа/поражение в основное время, но без шайб (0:0), как в КХЛ.
  • Почему дивизионы в отдельном файле? — чтобы не усложнять main.py; divisions.py переиспользует его функции, ничего в нём не меняя.
  • Как добавить новый сезон? — добавить CSV в khl_3/, описать конференции в CONFERENCESmain.py) и при необходимости дивизионы в DIVISIONSdivisions.py).