实用脚本统计撞墙式配合完成了几次?

wen 实用脚本 3

本文目录导读:

实用脚本统计撞墙式配合完成了几次?

  1. 先明确判定逻辑
  2. 假设你有的数据格式
  3. Python 脚本示例
  4. 输出结果
  5. 需要你确认的几个点

“撞墙式配合”在足球数据分析里通常叫 One-Two(二过一),要统计它完成了多少次,需要先明确数据来源和判定标准,因为“撞墙式配合”不是一个标准化事件,不同数据源的定义不同。

下面给你一个可落地的脚本思路和示例代码,你可以根据手头数据调整。


先明确判定逻辑

一次“撞墙式配合完成”通常需要满足:

  1. 球员A传球给球员B
  2. 球员B不做停顿/盘带,直接一脚回传给球员A(或A前插后的位置)
  3. 回传后A成功接到球(配合完成)
  4. 通常发生在推进方向上,且B的回传是“做墙”

简化判定条件(基于事件数据):

  • 事件序列:Pass(A→B) → Pass(B→A)
  • 两次传球时间间隔 ≤ 2~3 秒
  • 第二次传球是一脚出球(B接球后触球次数 ≤ 1)
  • 两次传球方向夹角合理(A→B 与 B→A 大致反向或侧向)
  • 最终A成功控球(下一次触球是A)

假设你有的数据格式

以常见的 event data(如 StatsBomb / Opta 风格)为例,每行一个事件:

match_id,period,minute,second,team,player,event_type,pass_recipient,pass_end_x,pass_end_y,start_x,start_y
1,1,10,05,TeamA,PlayerA,pass,PlayerB,60,40,40,30
1,1,10,07,TeamA,PlayerB,pass,PlayerA,45,32,60,40
...

Python 脚本示例

import pandas as pd
from math import atan2, degrees
# 读取事件数据
df = pd.read_csv("events.csv")
# 只保留传球事件,按时间排序
passes = df[df["event_type"] == "pass"].copy()
passes["time_sec"] = passes["minute"] * 60 + passes["second"]
passes = passes.sort_values(["match_id", "period", "time_sec"]).reset_index(drop=True)
def angle_diff(a1, a2):
    """两个方向角的差值(0~180度)"""
    d = abs(a1 - a2) % 360
    return min(d, 360 - d)
one_two_count = 0
details = []
# 遍历每个传球,找它后面紧接的传球
for i in range(len(passes) - 1):
    p1 = passes.iloc[i]
    p2 = passes.iloc[i + 1]
    # 同一场比赛、同一阶段、同一球队
    if p1["match_id"] != p2["match_id"]: continue
    if p1["period"] != p2["period"]: continue
    if p1["team"] != p2["team"]: continue
    # 条件1:A→B,B→A
    if p1["pass_recipient"] != p2["player"]: continue
    if p2["pass_recipient"] != p1["player"]: continue
    # 条件2:时间间隔 ≤ 3 秒(一脚出球)
    dt = p2["time_sec"] - p1["time_sec"]
    if dt > 3: continue
    # 条件3:方向大致反向(A→B 与 B→A 夹角 > 120°)
    ang1 = degrees(atan2(p1["pass_end_y"] - p1["start_y"],
                         p1["pass_end_x"] - p1["start_x"]))
    ang2 = degrees(atan2(p2["pass_end_y"] - p2["start_y"],
                         p2["pass_end_x"] - p2["start_x"]))
    if angle_diff(ang1, ang2) < 120: continue
    # 条件4:第二次传球后 A 接到球(下一事件是 A 的触球)
    if i + 2 < len(passes):
        p3 = passes.iloc[i + 2]
        if p3["player"] != p1["player"]: continue
    else:
        continue
    one_two_count += 1
    details.append({
        "match_id": p1["match_id"],
        "minute": p1["minute"],
        "player_a": p1["player"],
        "player_b": p1["player"],
    })
print(f"撞墙式配合完成次数:{one_two_count}")
pd.DataFrame(details).to_csv("one_two_details.csv", index=False)

输出结果

脚本会输出:

  • 总次数:撞墙式配合完成次数:N
  • 明细表 one_two_details.csv:每场比赛、每分钟、参与的 A/B 球员

需要你确认的几个点

不同数据源判定差异很大,建议你先明确:

问题 建议
数据源是什么?(StatsBomb / Opta / Wyscout / 自采集) 字段名需对应调整
是否要求“一脚出球”? 用 dt <= 3s 近似,或看触球数
是否要求向前推进? 加 p2.end_x > p2.start_x 或 x 前进条件
是否要求最终A成功控球? 看下一事件是否 A 触球
是否统计“尝试”还是“完成”? 完成 = 回传后A接到球

如果你告诉我你用的数据格式(字段名/样例几行),以及“完成”的判定标准(比如是否要求一脚出球、是否要求向前),我可以把脚本改成直接能跑你数据的版本。

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