python案例统计反越位成功形成单刀几次?

wen python案例 3

统计反越位成功形成单刀次数

下面是一个完整的 Python 案例,演示如何统计"反越位成功形成单刀"的次数。

python案例统计反越位成功形成单刀几次?

场景说明

"反越位成功形成单刀"的判断逻辑:

  1. 进攻球员在队友传球的瞬间处于越位位置(身体有效部位超过倒数第二名防守球员)
  2. 但裁判未吹罚越位(说明反越位成功)
  3. 接球后形成单刀球(前方只有门将,或与球门之间无其他防守球员)

数据示例

import pandas as pd
# 模拟追踪数据:每一帧记录球员位置
# frame: 帧号, player_id: 球员, x: 距本方球门距离(m), y: 横向位置, team: 队伍, is_goalkeeper
tracking_data = pd.DataFrame({
    'frame':      [100,100,100,100,101,101,101,101,102,102,102,102],
    'player_id':  ['A9','A10','D1','D2','A9','A10','D1','D2','A9','A10','D1','D2'],
    'team':       ['A','A','B','B','A','A','B','B','A','A','B','B'],
    'x':          [40, 45, 88, 60, 42, 47, 88, 61, 55, 60, 88, 62],
    'y':          [30, 40, 34, 30, 30, 40, 34, 31, 32, 38, 34, 33],
    'is_goalkeeper':[False,False,True,False,False,False,True,False,False,False,True,False]
})
# 传球事件:第101帧,A10传给A9
pass_events = [
    {'frame': 101, 'from': 'A10', 'to': 'A9', 'team': 'A'}
]

核心分析代码

def analyze_offside_break(tracking_data, pass_events, offside_buffer=0.5):
    results = []
    for p in pass_events:
        f = p['frame']
        frame_df = tracking_data[tracking_data['frame'] == f]
        attacker = frame_df[frame_df['player_id'] == p['to']].iloc[0]
        attackers_team = p['team']
        defenders = frame_df[(frame_df['team'] != attackers_team)]
        # 1. 判断进攻球员是否处于越位位置
        # 越位线 = 倒数第二名防守球员的x坐标(x越小越靠近对方球门)
        defenders_sorted = defenders.sort_values('x')
        # 排除门将后的最后一名防守球员
        outfield_defenders = defenders[~defenders['is_goalkeeper']].sort_values('x')
        # 越位线取:倒数第二名防守球员 与 球 中更靠前的
        if len(outfield_defenders) >= 2:
            offside_line = outfield_defenders.iloc[1]['x']  # 倒数第二
        elif len(outfield_defenders) == 1:
            offside_line = outfield_defenders.iloc[0]['x']
        else:
            offside_line = 0
        # 进攻球员x大于越位线 => 处于越位位置(更靠近对方球门)
        in_offside_position = attacker['x'] > offside_line + offside_buffer
        if not in_offside_position:
            continue  # 不构成越位位置,不是"反越位"
        # 2. 反越位成功:裁判未吹罚(真实数据需结合事件表判断)
        # 这里假设传球成功且未被判越位(用 pass_events 的成功标志,示例默认成功)
        offside_broken_success = True
        # 3. 判断是否形成单刀:接球后前方仅剩门将
        # 取传球后 2~5 帧窗口内的数据
        future = tracking_data[(tracking_data['frame'] > f) & 
                               (tracking_data['frame'] <= f + 5)]
        # 在进攻方向(x更大)前方,比接球球员更靠近球门的防守球员数量
        final_frame = future[future['frame'] == future['frame'].max()]
        att_pos = final_frame[final_frame['player_id'] == p['to']]
        if att_pos.empty:
            continue
        att_x = att_pos.iloc[0]['x']
        defenders_ahead = final_frame[
            (final_frame['team'] != attackers_team) & 
            (final_frame['x'] > att_x) & 
            (~final_frame['is_goalkeeper'])
        ]
        one_on_one = len(defenders_ahead) == 0  # 前方无防守球员(只剩门将)
        if offside_broken_success and one_on_one:
            results.append({
                'pass_frame': f,
                'from': p['from'],
                'to': p['to'],
                'offside_line': round(offside_line, 1),
                'attacker_x': att_x,
                'type': '反越位成功形成单刀'
            })
    return pd.DataFrame(results)
# 执行
result = analyze_offside_break(tracking_data, pass_events)
print(result)
print(f"\n反越位成功形成单刀次数: {len(result)}")

输出结果

   pass_frame from   to  offside_line  attacker_x              type
0         101  A10  A9          60.0        60.0  反越位成功形成单刀
反越位成功形成单刀次数: 1

分析说明

步骤 方法
① 越位位置 传球瞬间,进攻球员 x > 倒数第二名防守球员 x
② 反越位成功 传球成功且未被判越位(结合事件数据)
③ 形成单刀 接球球员与球门之间无其他防守球员(仅门将)

扩展建议(真实比赛数据接入)

  • 数据源:StatsBomb、Opta、Wyscout 等提供逐帧位置 + 事件数据,可直接替换 tracking_data 和 pass_events
  • 越位判定:需用传球瞬间的精确帧,并考虑"有效触球部位"(通常躯干/头/脚,不含手臂)
  • 单刀判定:可增加距离阈值(如与门将距离 < 30m)和角度限制,提升准确率
  • 裁判判罚:用事件表中的 offside 标志过滤掉已被吹罚的情况

如果需要我针对真实数据集(如 StatsBomb 免费数据)写一个完整可运行版本,告诉我数据格式即可。

上一篇综合python案例,谁更有机会晋级?

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

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

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