python案例如何分析守门员的出击范围?

wen python案例 3

守门员出击范围分析案例

下面通过一个完整的 Python 案例,演示如何分析守门员的出击范围,数据来源可以是 StatsBomb 开放数据(免费)。

python案例如何分析守门员的出击范围?

分析思路

出击范围通常从以下维度衡量:

  1. 平均出击位置(距球门线距离)
  2. 出击热区分布(六码区/小禁区/大禁区/禁区外)
  3. 出击类型:角球出击、传中出击、清道夫式出击
  4. 成功率(出击是否成功夺球)

准备数据

使用 StatsBomb 免费开放数据(如女足欧洲杯、世界杯等赛事)。

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsbombpy import sb
# 获取比赛列表
matches = sb.matches(competition_id=72, season_id=107)  # 女足欧洲杯2022
match_id = matches.iloc[0]['match_id']
# 获取事件数据
events = sb.events(match_id=match_id)

筛选门将出击事件

StatsBomb 中门将相关事件主要有:

  • Goalkeeper 类型下:Save、Punch、Catch、Collected、Smother、Keeper Sweeper
# 筛选门将事件
gk_events = events[events['type'] == 'Goalkeeper'].copy()
# 提取坐标
gk_events[['x', 'y']] = gk_events['location'].apply(
    pd.Series
)
# 只看门将出击类动作(离开球门线的动作)
sweeper_types = ['Collected', 'Punch', 'Smother', 'Keeper Sweeper']
gk_sweeper = gk_events[gk_events['goalkeeper_type'].isin(sweeper_types)]

计算出击范围指标

# 1. 平均出击位置(x 越小越靠本方球门,StatsBomb 中 0=本方底线,120=对方底线)
avg_x = gk_sweeper['x'].mean()
# 2. 转换为距本方球门线的距离(1 StatsBomb 单位 ≈ 0.915 米)
distance_m = avg_x * 0.915
print(f"门将平均出击位置 x = {avg_x:.1f}(距球门线约 {distance_m:.1f} 米)")
# 3. 区域划分统计(球门线=0,六码区≈5.5m,小禁区≈18.3m,大禁区≈40.3m)
def zone(x):
    if x < 6:      return '球门线上'
    elif x < 12:   return '六码区'
    elif x < 20:   return '小禁区'
    elif x < 44:   return '大禁区'
    else:          return '禁区外'
gk_sweeper['zone'] = gk_sweeper['x'].apply(zone)
zone_dist = gk_sweeper['zone'].value_counts()
print(zone_dist)

可视化出击热区

from mplsoccer import Pitch
pitch = Pitch(pitch_type='statsbomb', line_color='black', half=True)
fig, ax = pitch.draw(figsize=(8, 6))
# 六边形热区(只看左半场)
pitch.kdeplot(
    gk_sweeper['x'], gk_sweeper['y'],
    ax=ax, fill=True, levels=50, cmap='Reds',
    thresh=0.05
)
ax.set_title("门将出击位置热区")
plt.show()

对比两名门将

def analyze_gk(match_id, player_name):
    ev = sb.events(match_id=match_id)
    gk = ev[(ev['type']=='Goalkeeper') & (ev['player']==player_name)].copy()
    gk[['x','y']] = gk['location'].apply(pd.Series)
    sweeper = gk[gk['goalkeeper_type'].isin(sweeper_types)]
    return {
        'player': player_name,
        'avg_x': sweeper['x'].mean(),
        'max_x': sweeper['x'].max(),
        'n_sweeper': len(sweeper),
        'outside_box': (sweeper['x'] > 44).sum()
    }
gk1 = analyze_gk(match_id, 'Christiane Endler')
gk2 = analyze_gk(match_id, 'Mary Earps')
print(pd.DataFrame([gk1, gk2]))

进阶指标(可选)

指标 计算方式 含义
出击成功率 成功夺球次数 / 总出击次数 判断鲁莽程度
出击范围标准差 std(x) 活动范围广度
出击纵深 max(x) 最远出击位置
场均出击次数 出击次数 / 出场数 主动程度
传中处理率 出击传中数 / 对手传中总数 覆盖能力
# 出击成功率示例(Punch、Collected 一般视为成功)
success_types = ['Collected', 'Punch', 'Catch']
gk = gk_events[gk_events['goalkeeper_type'].isin(sweeper_types)]
success_rate = gk['goalkeeper_type'].isin(success_types).mean()
print(f"出击成功率: {success_rate:.1%}")

常见数据源推荐

  • StatsBomb(免费开放部分,含门将事件标签)
  • FBref(进阶门将数据:Defensive Actions Outside Penalty Area 等)
  • Wyscout(需付费)、SofaScore API

结论示例输出

门将平均出击位置 x≈13(距球门线约 12 米),大部分出击集中在小禁区边缘;出击传中和角球占比高,属于典型的"清道夫门将",防线压得较高。


如果你有具体的赛事 ID、数据文件(CSV/JSON)或想分析某位门将,我可以基于你的数据写出完整脚本。

抱歉,评论功能暂时关闭!

友情链接攻略窝 · 礼包窝 · 配置窝 · 换算窝 · 算法窝 · 查文窝 · 手册窝 · 问答窝 · 全文搜 · 手册库
相关站点礼包窝 · 查文窝