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_namecompetition_name列中删除重复项。

    sb.competitions().drop_duplicates(['country_name', 'competition_name'])

    运行结果


    我们可以看到,Statsbomb的免费数据有世界杯、欧冠、西甲、英超等联赛。如果想获取Statsbomb 有更多的比赛数据,只有付费购买,通过 API 访问来获取。OK,接下来让我们探索一下数据集中提供的比赛数据:2018 年世界杯!

    探索数据

    2.1查找数据

    要探索 2018 年世界杯的数据,我们将需要competition_idseason_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"]
            )

    运行结果


    这就是法国队这场比赛(第一次换人)球员们之间的传球图,其中红线越粗他们之前的传球频率越多……

    结束语

    以上就是一些足球数据分析的内容,我们不仅可以可以可视化传球神经网络,还可以绘制出进攻热力图,雷达图等等,让我们在接下来的日子里慢慢来探索吧!

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python中的足球数据应用指南(第一部分)

    发表评论