实用脚本如何分析球员跑动热点图?

wen 实用脚本 3

本文目录导读:

实用脚本如何分析球员跑动热点图?

  1. 数据来源与格式
  2. 核心分析脚本框架
  3. 战术解读脚本(自动生成洞察)
  4. 进阶:时间切片与动态热点
  5. 实战注意事项
  6. 推荐工具链

分析球员跑动热点图,需要从数据获取、可视化处理、战术解读三个层面展开,下面是一套可落地的实用脚本思路(以Python为主),涵盖从原始数据到战术洞察的完整流程。


数据来源与格式

热点图分析的前提是带坐标的跑动/触球数据:

数据源 格式 说明
StatsBomb Open Data JSON 含每个事件的 x,y 坐标(0-120 × 0-80)
Opta / Wyscout CSV/JSON 需付费,含球员追踪点
比赛视频 + 追踪系统 CSV 每帧球员坐标(如 25fps)
手动标注 CSV x, y, timestamp, player_id

典型字段:player_id, x, y, event_type, timestamp


核心分析脚本框架

数据清洗与坐标归一化

import pandas as pd
import numpy as np
def load_tracking_data(path):
    df = pd.read_csv(path)
    # 统一到 0-100 × 0-100 的相对坐标(便于跨场地比较)
    df['x_norm'] = df['x'] / df['x'].max() * 100
    df['y_norm'] = df['y'] / df['y'].max() * 100
    # 只保留进攻方向一致的半场(可选:翻转客队)
    return df
def normalize_direction(df, team='home'):
    if team == 'away':
        df['x_norm'] = 100 - df['x_norm']
        df['y_norm'] = 100 - df['y_norm']
    return df

热点图生成(KDE 核密度估计)

import matplotlib.pyplot as plt
import seaborn as sns
from scipy.stats import gaussian_kde
def plot_heatmap(df, player_id, title=''):
    pts = df[df['player_id'] == player_id][['x_norm','y_norm']].values.T
    kde = gaussian_kde(pts, bw_method=0.15)
    # 生成网格
    xi, yi = np.mgrid[0:100:200j, 0:100:200j]
    zi = kde(np.vstack([xi.ravel(), yi.ravel()])).reshape(xi.shape)
    fig, ax = plt.subplots(figsize=(8,6))
    # 画球场底图
    draw_pitch(ax)
    ax.contourf(xi, yi, zi, levels=20, cmap='hot', alpha=0.7)
    ax.set_title(title)
    plt.show()

分区统计(Zone Analysis)

把球场切成 3×5 或 6×5 网格,统计各区域停留时长/触球次数:

def zone_stats(df, player_id, x_bins=6, y_bins=5):
    sub = df[df['player_id'] == player_id].copy()
    sub['zone_x'] = pd.cut(sub['x_norm'], bins=x_bins, labels=False)
    sub['zone_y'] = pd.cut(sub['y_norm'], bins=y_bins, labels=False)
    # 若数据含时长,用 sum;否则用 count 近似
    pivot = sub.pivot_table(index='zone_y', columns='zone_x',
                            values='duration', aggfunc='sum', fill_value=0)
    return pivot

多球员对比热图

def compare_heatmaps(df, players, figsize=(15,5)):
    fig, axes = plt.subplots(1, len(players), figsize=figsize)
    for ax, pid in zip(axes, players):
        pts = df[df['player_id']==pid][['x_norm','y_norm']].values.T
        sns.kdeplot(x=pts[0], y=pts[1], cmap='Reds', fill=True,
                    bw_adjust=0.5, ax=ax, thresh=0.05)
        draw_pitch(ax)
        ax.set_title(f'Player {pid}')
    plt.tight_layout()

战术解读脚本(自动生成洞察)

数据可视化之外,脚本应输出可解释指标:

def tactical_metrics(df, player_id):
    sub = df[df['player_id']==pid]
    return {
        '平均站位_x': sub['x_norm'].mean(),          # 进攻推进程度
        '平均站位_y': sub['y_norm'].mean(),          # 左右偏斜
        '活动范围_面积': convex_hull_area(sub),       # 覆盖面积
        '前场占比': (sub['x_norm']>66).mean(),        # 高位活动比例
        '边路占比': ((sub['y_norm']<20)|(sub['y_norm']>80)).mean(),
        '热点中心': gaussian_kde(sub[['x_norm','y_norm']].T.values).covariance,
    }

解读维度:

指标 战术含义
平均x偏高 + 面积小 固定高位站位(如影锋)
面积大 + 分散 扫荡型中场/B2B
边路占比 >60% 边锋/边后卫
两个热点峰值 双角色球员(如内收边卫)
前场占比低但面积大 后场组织核心

进阶:时间切片与动态热点

分析不同比赛阶段的热点变化(判断体能下降/战术调整):

def time_sliced_heatmap(df, pid, intervals=[(0,15),(15,30),(30,45),
                                            (45,60),(60,75),(75,90)]):
    fig, axes = plt.subplots(2,3, figsize=(15,8))
    for ax, (t0,t1) in zip(axes.flat, intervals):
        sub = df[(df['player_id']==pid) &
                 (df['minute']>=t0) & (df['minute']<t1)]
        if len(sub) > 10:
            sns.kdeplot(data=sub, x='x_norm', y='y_norm',
                        fill=True, cmap='Blues', ax=ax, thresh=0.05)
        draw_pitch(ax); ax.set_title(f'{t0}-{t1}min')

用途:观察下半场活动范围缩小 → 体能问题;后半段热点前移 → 球队追分。


实战注意事项

  1. 样本量:单场 KDE 易受偶然事件干扰,建议 3-5 场滚动平均。
  2. bw_method 调参:带宽过小→碎片化;过大→糊成一团,追踪数据建议 0.05-0.1,事件数据 0.15-0.25。
  3. 坐标方向统一:客队需翻转,否则热点图无法横向对比。
  4. 区分"跑动"与"触球":追踪数据反映站位,事件数据反映参与度,两者热点含义不同——前者看覆盖,后者看威胁。
  5. 结合比赛情境:红牌、领先/落后、对手强度都会显著改变热点形态,需在报告中标明。

推荐工具链

  • 可视化:mplsoccer(专业球场绘图库)、seaborn KDE
  • 数据处理:pandas + scipy.stats.gaussian_kde
  • 数据源:StatsBomb Open Data(免费入门)、SkillCorner(追踪数据)
  • 快速原型:pyheatmap / plotly 交互式热图

如果需要,我可以针对具体数据格式(如 StatsBomb JSON 或 SkillCorner 追踪 CSV)写出可直接运行的完整脚本。

上一篇实用脚本统计角球数哪边领先?

下一篇当前分类已是最新一篇

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