Поиск по сайту Поиск

Панды в Премьер‑лиге

Очень жаль, но панды не играют в футбол. Поэтому в этой статье речь пойдёт о возможностях библиотеки “Pandas”, название которой происходит от термина “panel data”. Сегодня мы расскажем, как с её помощью можно проанализировать статистику игр футбольных команд в Премьер-лиге.

Английская Премьер-лига — одно из самых обсуждаемых событий в футбольном мире. Фанаты делают предположения, а букмекерские конторы принимают ставки на то, кто же займёт призовые места. В этом сезоне чемпионом второй раз подряд стал "Манчестер Сити". Насколько вероятным такой исход является с точки зрения Data Science?

Исследователь Стивен Фордхэм (Stephen Fordham) из Борнмутского университета решил продемонстрировать, как можно использовать Python-библиотеку Pandas для анализа таблицы результатов футбольных клубов.

Парсинг сайтов

Для начала добудем саму таблицу с результатами. В Pandas есть встроенная функция read_html, которая использует библиотеки lxml и Beautiful Soup для автоматического сбора данных из HTML-файлов в виде объектов DataFrame. Установим несколько дополнительных модулей, введя в терминале команды:

pip install lxml
pip install beautifulsoup4 html5lib

Метод read_html имеет ряд настраиваемых параметров, но по умолчанию он пытается найти и проанализировать любые табличные данные в html-тегах <table>, собирая их в список DataFrame.

Далее импортируем библиотеку pandas и используем функцию read_html, чтобы проанализировать таблицу Премьер-лиги и присвоить её переменной prem_table. Так мы получим список, из которого возьмём первый элемент — он будет содержать в себе последние доступные результаты.

Поскольку основное внимание сосредоточено на гонке за 4 призовых места, мы отобразим 6 первых записей в таблице с помощью метода .head. Чтобы убедиться, что с данными всё в порядке, можно использовать атрибут shape. Он показывает размер таблицы, в нашем случае в ней 21 строка и 12 столбцов. Проверка оказалась полезной, так как Python начинает считать строки с индекса 0, а в Премьер-лиге всего 20 команд. Похоже, в нашей таблице есть лишние данные. Раз с первыми значениями всё хорошо, проблема должна быть в какой-то дополнительной строке в конце DataFrame.

import pandas as pd

prem_table = pd.read_html('https://www.bbc.co.uk/sport/football/premier-league/table')
Premier_table = prem_table[0]

print(len(prem_table))
print(type(prem_table))

print(Premier_table.head(6))

# Output
1
<class 'list'>
https://cdn-images-1.medium.com/max/1600/1*Me_kYOQ-wvsMkrJxNs_Hlw.png

Перед тем как начать предварительный анализ, мы почистим данные. Столбец “Unnamed: 1” явно не несёт в себе полезной информации, поэтому удалим его с помощью метода drop с аргументом axis=1:

Premier_table.columns
Index(['Unnamed: 0', 'Unnamed: 1', 'Team', 'P', 'W', 'D', 'L', 'F', 'A', 'GD',
       'Pts', 'Form'],
      dtype='object')

Premier_league = Premier_table.drop(['Unnamed: 1'], axis=1)
Premier_league.head(6)

Результат:

https://cdn-images-1.medium.com/max/1600/1*Wj7YsxcGVXMCFCFEuaQQng.png

Типы данных в DataFrame

Каждый столбец в DataFrame можно представить как Series, где должны быть только однотипные данные. Для дальнейшего анализа попробуем расшифровать тип каждой Series.

Взглянув на таблицу, можно сразу предположить, что столбец “Team” содержит в себе строки, а “P” (количество сыгранных игр) — целочисленные значения. Но лучше не доверять предположениям и использовать атрибут dtypes или метод info.

https://cdn-images-1.medium.com/max/1600/1*ybBy5j3BWUYGJ8dB1zVbRA.png

Видим, что все Series содержат в себе данные “object”, то есть строковые значения. Для выполнения численных расчётов нам необходимо преобразовать типы некоторых из них. В Python это тривиальная задача: мы просто используем метод pandas.to_numeric.

Изменим тип данных нескольких столбцов на float:

https://cdn-images-1.medium.com/max/1600/1*8J-RefYIzkSmV-fNfF2iFQ.png

Очищаем DataFrame

Вернёмся к нашим лишним строкам и посмотрим на три последних записи в DataFrame:

https://cdn-images-1.medium.com/max/1600/1*FK26j0rXj7s9dgZz5v--Vg.png

В последней строке содержатся ненужные метаданные. Чтобы удалить их, снова используем метод drop, но на этот раз без параметра axis=1 (поскольку обрабатываем строку, а не столбец). С помощью атрибута shape убедимся, что всё прошло успешно:

Table.drop(Table.tail(1).index, inplace=True)
Table.tail(3)
Table.shape

# Output

(20, 12)
https://cdn-images-1.medium.com/max/1600/1*J31bdE0x3JRrlYuBSxDYcA.png

Теперь посмотрим на столбец “Unnamed: 0”. Его название явно не согласуется с содержимым (с позицией команды в общем зачёте). Исправим это методом Pandas Dataframe.rename с аргументом Inplace=True, чтобы применить изменения к исходному DataFrame.

Table.columns
Index(['Unnamed: 0', 'Team', 'P', 'W', 'D', 'L', 'F', 'A', 'GD', 'Pts',
       'Form'],
      dtype='object')

Table.rename(columns={'Unnamed: 0':'Position'}, inplace=True)
Table.head()
https://cdn-images-1.medium.com/max/1600/1*1uKGTQGBdXiCjnKYHuIVLw.png

Создаём новые столбцы

Наш DataFrame теперь настроен. На этом этапе стоит попробовать создать несколько новых столбцов и проверить, будет ли для них работать преобразование строк в числа, сделанное нами ранее.

Сформируем столбец под названием «Соотношение голов» (“Goal Ratio”), показывающий отношение забитых мячей к пропущенным. Для этого нужно поделить столбец “F” на столбец “A” и округлить значения до одного знака после запятой. По умолчанию новые данные добавляются в конец DataFrame:

https://cdn-images-1.medium.com/max/1600/1*pCMYBIMuBnHQExFaO-OUsw.png

Чтобы переместить столбец, можно просто переопределить таблицу, указав нужный порядок:

https://cdn-images-1.medium.com/max/1600/1*sOBYv2xlg_pf85SqRROYyA.png

Мы удалили столбец “Form”, чтобы данные выглядели более аккуратными.

Фильтруем DataFrame

Теперь наша таблица оформлена подобающим образом. Давайте начнём анализ с простого вопроса, например: «Какие команды сыграли на одну игру меньше своих соперников?». Так как все команды на момент написания статьи сыграли 34 или 35 игр, мы просто выводим те, у которых значение столбца “P” равно 34. Для фильтрации используем логическое индексирование:

https://cdn-images-1.medium.com/max/1600/1*_sSnLNfxrTE8MRRoV3ksEw.png

Теперь давайте определим, у какой команды было больше всего результатов «ничья» (столбец “D”).

Клуб "Саутгемптон" изо всех сил пытается избежать вылета, повлияет ли это на их позицию?

https://cdn-images-1.medium.com/max/1600/1*ZDZWg6sJ3ozw_NWcn2H_Vg.png

Наконец, создадим ещё два столбца: число забитых и пропущенных голов за игру (“Goals/game” и “Goal conceded/game”). Отсортируем значения методом sort_values:

Table['Goals/game'] = round((Table.F / Table.P), 1)
Table['Goals conceded/game'] = round((Table['A'] / Table['P']), 1)
Table.sort_values(['Goals/game', 'Goal Ratio']).head(5)

После «Хаддерсфилда» и «Фулхэма» у клуба «Кардифф» третье худшее соотношение забитых и пропущенных голов. Смогут ли они продолжать бороться за более высокое место в таблице со своим ближайшим соперником, клубом «Брайтон»? Достаточное ли у них нападение, уязвима ли защита?

Мы можем выяснить это с помощью Pandas!

https://cdn-images-1.medium.com/max/1600/1*2fo1Avu7ipQAH9ZIhAoCog.png

Что ж, похоже, их шансы невысоки.

Хотя английская Премьер-лига завершилась, в России она ещё продолжается — вы можете оценить статистику главных претендентов на первенство и предположить, кто же станет чемпионом. А если вы уже давно знакомы с анализом данных, то для больших вычислений рекомендуем воспользоваться нашими серверами с GPU NVIDIA Tesla V100.

Заключение

Надеемся, что представленные в этой статье функции Pandas помогут вам в анализе данных. Напоследок один совет: не анализируйте статистику Премьер-лиги во время соревнований, поскольку пока вы пишете код, данные успеют поменяться. Все расчёты стоит выполнять после матчей. А пока — устраивайтесь поудобнее и наблюдайте за игрой!

С оригинальной статьёй можно ознакомиться на портале towardsdatascience.com.

Аннуитетный и дифференцированный платеж: что это и что выгоднее
При оформлении кредита заемщик сталкивается с выбором схемы погашения — аннуитетный или дифференцированный платеж. От этого решения зависит не только...
Read More
Понятие СВОП на бирже простым языком: что это и как используется
Своп — это один из тех финансовых инструментов, о которых часто говорят «слишком сложно», хотя по сути он работает как...
Read More
На основании чего действует ИП в договоре и как правильно оформить этот пункт
Ошибка в формулировке может создать проблемы при проверках, в суде или при работе с банком. Например, если указать, что ИП...
Read More
Как работает гибридный график, и зачем бизнесу переходить на смешанный формат
Подробно разбираем гибридный график работы: плюсы и минусы для бизнеса, сотрудников и HR, а также рассказываем, как пошагово внедрить его...
Read More
Пирамида Дилтса: логические уровни и их практическое применение
Разбор пирамиды Дилтса, ее уровней и способов применения в личном развитии и управлении. (далее…)
Read More
Как правильно установить и оформить сменный график работы
Разъясняем, как грамотно оформить такой график, какие нюансы учесть и какие варианты возможны. (далее…)
Read More
Как не потерять клиентов, когда мессенджеры перестают работать
За последние годы бизнес и клиенты привыкли к тому, что многое решается за один клик, а от записи до визита...
Read More
Как предоставляется отпуск и назначается пособие по уходу за ребенком в 2026 году
Разбираем актуальные правила предоставления отпусков и выплаты пособий в 2026 году, необходимые условия, порядок оформления и другие животрепещущие вопросы. (далее…)
Read More
Письмо о возврате ошибочно перечисленных денежных средств: образец и правила оформления
Устные договоренности в бизнесе работают далеко не всегда. Сегодня вам пообещали вернуть деньги на следующей неделе, а через месяц об...
Read More
Как правильно составить акт приема-передачи документов
Представьте ситуацию: вы передали бухгалтеру оригиналы договоров и первички, а через пару месяцев выяснилось, что часть документов пропала. Без акта...
Read More