实用脚本统计脚后跟传球成功几次?

wen 实用脚本 3

统计脚后跟传球成功次数的脚本方案

你问的是"实际脚本统计脚后跟传球",我理解你想用代码从足球比赛数据(如事件数据、追踪数据)中自动统计"脚后跟传球(backheel pass)"的成功次数,下面给你一个可落地的方案。

实用脚本统计脚后跟传球成功几次?

数据来源选择

数据源 是否含脚后跟标签 说明
StatsBomb Open Data ✅ 有 pass.body_part 和 technique 免费,推荐
Opta / Stats Perform ✅ 有 qualifier 商业
Wyscout ⚠️ 部分 需映射
追踪数据(坐标) ❌ 需自己判定 需几何规则

最省事:StatsBomb 的 pass.technique 字段里有 "Backheel" 值,直接过滤即可。

核心脚本(基于 StatsBomb 事件数据)

import pandas as pd
from statsbombpy import sb
def count_backheel_passes(match_id: int):
    events = sb.events(match_id=match_id)
    # 只取传球事件
    passes = events[events['type'] == 'Pass'].copy()
    # 提取 technique 字段(可能是 list 或 str)
    def get_tech(t):
        if isinstance(t, list):
            return t
        if isinstance(t, str):
            return [t]
        return []
    passes['tech_list'] = passes['pass_technique'].apply(get_tech)
    # 筛选脚后跟传球
    backheels = passes[passes['tech_list'].apply(lambda x: 'Backheel' in x)]
    # 判定成功:StatsBomb 中传球成功 = 没有 pass_outcome(即 outcome 为空)
    backheels = backheels.copy()
    backheels['success'] = backheels['pass_outcome'].isna()
    total = len(backheels)
    success = int(backheels['success'].sum())
    # 按球员统计
    by_player = (backheels.groupby('player')['success']
                 .agg(['count', 'sum'])
                 .rename(columns={'count': 'attempts', 'sum': 'successes'}))
    by_player['rate'] = (by_player['successes'] / by_player['attempts']).round(2)
    print(f"比赛 {match_id}: 脚后跟传球 {total} 次,成功 {success} 次,成功率 {success/total:.1%}" if total else "无脚后跟传球")
    return backheels, by_player
# 示例
match_id = 3788741  # 可换成任意 StatsBomb 比赛ID
backheels, by_player = count_backheel_passes(match_id)
print(by_player.sort_values('successes', ascending=False))

如果没有 technique 标签(用追踪数据判定)

若只有坐标数据,用几何规则近似判定"脚后跟传球":

import numpy as np
def is_backheel_pass(passer_pos, receiver_pos, pass_end, attacking_dir=1):
    """
    passer_pos: (x, y) 传球者位置
    pass_end:   (x, y) 球落点
    attacking_dir: +1 表示向右进攻
    规则:球的行进方向与球员朝向相反 → 近似脚后跟
    """
    dx = (pass_end[0] - passer_pos[0]) * attacking_dir
    # 球向后传(与进攻方向相反)且距离短,才可能是脚后跟
    if dx > -2:          # 不是向后传
        return False
    dist = np.hypot(pass_end[0]-passer_pos[0], pass_end[1]-passer_pos[1])
    return dist < 15     # 短距离回做

⚠️ 追踪数据判定误差大,只能算"疑似脚后跟",建议只用事件数据做正式统计。

批量统计整届赛事

def tournament_backheel_stats(competition_id, season_id):
    matches = sb.matches(competition_id=competition_id, season_id=season_id)
    all_rows = []
    for mid in matches['match_id']:
        bh, _ = count_backheel_passes(mid)
        if len(bh):
            bh['match_id'] = mid
            all_rows.append(bh)
    if not all_rows:
        return pd.DataFrame()
    df = pd.concat(all_rows)
    summary = (df.groupby('player')
               .agg(attempts=('success','size'), successes=('success','sum')))
    summary['rate'] = (summary.successes/summary.attempts).round(2)
    return summary.sort_values('successes', ascending=False)
# 例:2022世界杯
# print(tournament_backheel_stats(43, 106))

注意事项

  1. 字段名版本差异:statsbombpy 不同版本列名可能是 pass_technique 或嵌套在 pass 字典里,先 print(events.columns) 确认。
  2. "成功"定义:StatsBomb 中传球成功 = pass_outcome 为空(未出界/未被断/未丢球权),若你的数据源用 accurate=True/False,改判据即可。
  3. 脚后跟 ≠ 所有回传:一定要用 technique 标签,别用方向规则替代,否则会把普通回传也算进去。
  4. 边界情况:脚后跟传球被犯规中断、形成射门等情况,按你的统计口径决定算不算"成功"。

需要我帮你改成 Opta XML 解析版、Wyscout API 版,或加上可视化(球员脚后跟传球热图)吗?告诉我你的数据源,我直接给你对应脚本。

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