Python中的足球数据应用指南(第一部分)
前言
每一分钟的足球比赛都孕育着能够激发人们高品质洞察力的数据,这些数据可以用于球员招募、比赛分析,并帮助教练做出更明智的决策。然而,遗憾的是,目前大多数免费的在线数据集仅包含基本统计信息,如积分、球队名称和比赛日期。仅凭这些基本统计数据,我们无法获得太多有价值的信息。为了获取更深入的统计数据,可以尝试进行爬虫,但是要花费大量的时间,所以我们可以探索一些免费分享的数据。在本文中,我们将探索Statsbomb在其Python包statsbombpy中分享的所有免费足球数据。这些数据将让我们深入了解比赛,解析在数字背后的足球故事。不再是些基础统计数据,我们将能够探索足球世界的布局,挖掘球员的精彩瞬间,揭示精彩的奥妙。让我们一起探索这些数据,为你对足球理解注入新的能量。接下来,让我们开始启程。
准备工作
1.1安装statsbombpy
获取Statsbomb分享的所有足球数据,我们需要安装statsbombpy
pip install statsbombpy
1.2导入statsbombpy
安装之后,我们将其导入
from statsbombpy import sb
1.3查看免费比赛
查看 Statsbomb 免费分享的所有比赛,您只需运行sb.competition()
competitions=sb.competitions()
如果仅显示比赛,也可以在country_name和competition_name列中删除重复项。
sb.competitions().drop_duplicates(['country_name', 'competition_name'])
运行结果
我们可以看到,Statsbomb的免费数据有世界杯、欧冠、西甲、英超等联赛。如果想获取Statsbomb 有更多的比赛数据,只有付费购买,通过 API 访问来获取。OK,接下来让我们探索一下数据集中提供的比赛数据:2018 年世界杯!
探索数据
2.1查找数据
要探索 2018 年世界杯的数据,我们将需要competition_id和season_id。从提供的信息来看,2018年世界杯的competition_id是43,对应的competition_id是3
WorldCup_2018 = sb.matches(competition_id=43, season_id=3)
WorldCup_2018.head(5)
运行结果
2.2探索2018年世界杯
该WorldCup_2018数据框包含 22 列,为我们足球分析提供了良好的基础。为了获得有关特定比赛的更多信息,我们将需要match_id。
很遗憾小编是意大利球迷在2018年世界杯并没有看到他们的身影,但是对足球的热爱仍在继续。接下来我们查询2018 年世界杯淘汰赛法国队与阿根廷队的比赛 ,ID 为 7580。
WorldCup_2018_FRA_ARG = 7580
FRA_ARG=WorldCup_2018[WorldCup_2018['match_id']==WorldCup_2018_FRA_ARG]
运行结果
结果显示7580是该比赛的id,现在让我们来看看这场惊心动魄的比赛发生了什么事情吧!
2.2.1查看比赛阵容
我们来看看法国vs阿根廷的阵容吧!
lineups = sb.lineups(match_id=7580)
当我们查看lineups的数据类型是会发现他是字典( dict)。所以我们打印他的键(key)列表。
lineups.keys()
Out[23]: dict_keys(['France', 'Argentina'])
下一步我们通过键(key)来了解两队的阵容
法国队
France_lineups=lineups['France']
结果显示
阿根廷队
Argentina_lineups=lineups['Argentina']
结果显示
2.2.2查看比赛事件
如果想要查看比赛事件,我们需要再次查看比赛的id。
FRA_ARG_events = sb.events(match_id=7580)
让我们看看FRA_ARG_events的所有列吧!
FRA_ARG_events_columns=FRA_ARG_events.columns
运行结果
我们可以看到这个数据集中有很多信息。让我们选择几个重要的列,并对minutes和timestamp列进行排序。
FRA_ARG_df_events=FRA_ARG_events[['timestamp','team', 'type', 'minute', 'location', 'pass_end_location', 'player']]
FRA_ARG_df_events=FRA_ARG_events.sort_values(['minute', 'timestamp'])
让我们看看比赛最后时刻发什么了什么事情吧!
FRA_ARG_df_events_tail=FRA_ARG_df_events.tail(15)
运行结果
python可视化
现在到最激动人心的时候了,我们将数据可视化,首先我们开始做些准备工作!
3.1准备工作
为了方便查找数据以及可视化操作,我们安装mplsoccer库
pip install mplsoccer
接下来就是导入相关的库
import matplotlib.pyplot as plt
import numpy as np
from mplsoccer import Pitch, Sbopen
import pandas as pd
3.2计算球员的平均位置和传球次数
思路:计算每个球员的平均位置和传球次数,在遍历球员列表,合并传球坐标,然后算出平均坐,并计算传球数量。
players = df_pass["player_name"].unique()
scatter_data = [{
"player_name": name,
"x": np.mean(np.concatenate([df_pass.loc[df_pass["player_name"] == name, "x"].to_numpy(),
df_pass.loc[df_pass["pass_recipient_name"] == name, "end_x"].to_numpy()])),
"y": np.mean(np.concatenate([df_pass.loc[df_pass["player_name"] == name, "y"].to_numpy(),
df_pass.loc[df_pass["pass_recipient_name"] == name, "end_y"].to_numpy()])),
"no": df_pass[df_pass["player_name"] == name].shape[0]
} for name in players]
scatter_df = pd.DataFrame(scatter_data)
max_pass_no = scatter_df['no'].max()
scatter_df['marker_size'] = scatter_df['no'] / max_pass_no * 1500
查看法国队球员在第一次换人之前的传球数
pass_counts = df_pass.groupby("player_name").size()
运行结果
3.3绘制球员在球场上的散点图和球场
def draw_pitch_and_scatter(data_frame, ax, pitch_object):
pitch_object.scatter(
data_frame.x, data_frame.y,
s=data_frame.marker_size,
color='red',
edgecolors='grey',
linewidth=1,
alpha=1,
ax=ax["pitch"],
zorder=3
)
for index, row in data_frame.iterrows():
pitch_object.annotate(
row.player_name, xy=(row.x, row.y),
c='black',
va='center',
ha='center',
weight="bold",
size=16,
ax=ax["pitch"],
zorder=4
)
运行结果
3.4绘制球员之间的连线并且与散点图结合
将数据可视化,用以球员在球场上的位置和他们之间的传球关系。
def draw_lines(lines_df, scatter_df, ax, pitch_object):
for index, row in lines_df.iterrows():
players = row["pair_key"].split("_")
player1, player2 = players[0], players[1]
player1_coords = scatter_df.loc[scatter_df["player_name"] == player1, ['x', 'y']].iloc[0]
player2_coords = scatter_df.loc[scatter_df["player_name"] == player2, ['x', 'y']].iloc[0]
line_width = (row["pass_count"] / lines_df['pass_count'].max() * 10)
pitch_object.lines(
player1_coords.x, player1_coords.y,
player2_coords.x, player2_coords.y,
alpha=1,
lw=line_width,
zorder=2,
color="red",
ax=ax["pitch"]
)
运行结果
这就是法国队这场比赛(第一次换人)球员们之间的传球图,其中红线越粗他们之前的传球频率越多……
结束语
以上就是一些足球数据分析的内容,我们不仅可以可以可视化传球神经网络,还可以绘制出进攻热力图,雷达图等等,让我们在接下来的日子里慢慢来探索吧!