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

wen 实用脚本 2

本文目录导读:

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

  1. 方案一:纯Python逻辑(最易理解,适合处理JSON数据)
  2. 方案二:使用 Pandas(进阶版,处理大型CSV文件)
  3. 方案三:针对“视频标签”的简易脚本(适合手动打点)
  4. 重要提示(关于“撞墙”的定义)

在足球比赛中,“撞墙式配合”(也叫“二过一”)在足球统计里通常被归类为“最后一传”(Key Pass)或“直接传球”(One-touch Pass)的变体,但它没有标准化的官方统计字段,要统计这个,通常需要自定义脚本来处理事件数据(Event Data)。

这里为你提供三种不同难度的实用脚本方案,从纯Python逻辑使用数据分析库

纯Python逻辑(最易理解,适合处理JSON数据)

如果你有比赛的事件数据(通常包含x, y坐标,timestamp时间戳,playertype字段),这个脚本可以帮你识别出“短距离快速回传后直塞”的模式。

import json
from math import sqrt
# 假设数据格式为 [{'player': 10, 'type': 'pass', 'x': 50, 'y': 30, 'end_x': 40, 'end_y': 30, 'time': 10.2}, ...]
# 请根据你的实际数据修改这些字段名
def load_data(file_path):
    with open(file_path, 'r', encoding='utf-8') as f:
        return json.load(f)
def is_pass(event):
    """判断是不是传球"""
    return event.get('type') == 'pass'
def calculate_distance(x1, y1, x2, y2):
    """计算欧氏距离"""
    return sqrt((x2 - x1)**2 + (y2 - y1)**2)
def detect_wall_pass(events, max_time_gap=2.0, max_pass_distance=25.0):
    """
    撞墙式配合检测逻辑(简化版):
    1. A球员传给B球员(第一次传递)
    2. B球员不停球(或极短时间内)直接回传给A球员所在的附近区域(第二次传递,第一脚触球就传)
    3. A球员向前推进(第三次传递发生在更靠近球门的位置)
    """
    wall_pass_count = 0
    for i in range(len(events) - 2):
        # 获取连续的三个事件
        pass1 = events[i]
        pass2 = events[i + 1]
        pass3 = events[i + 2]
        # 条件1:都是传球
        if not (is_pass(pass1) and is_pass(pass2) and is_pass(pass3)):
            continue
        # 条件2:时间上很接近(一次触球)
        if (pass2.get('time', 0) - pass1.get('time', 0)) > max_time_gap:
            continue
        # 条件3:第一次传递的距离较短(短传)
        dist1 = calculate_distance(pass1.get('x'), pass1.get('y'),
                                   pass1.get('end_x'), pass1.get('end_y'))
        if dist1 > max_pass_distance:
            continue
        # 条件4:第二次传球是“回敲”(球回到了第一个传球者的附近)
        # 找第一个传球者的最终位置(假设pass1的end就是pass2的start,这里简化)
        # 实际上我们需要看pass2的x,y(起脚位置)是否接近pass1的x,y(发起位置)
        start_dist = calculate_distance(pass2.get('x'), pass2.get('y'),
                                        pass1.get('x'), pass1.get('y'))
        if start_dist > 15.0:  # 如果B球员接球位置离A球员太远,不算
            continue
        # 条件5:第三次传球必须向前推进(传向对方半场,或接近球门)
        if pass3.get('end_x') <= pass1.get('end_x'):
            continue  # 没有向前推进
        # 如果都满足,计数
        wall_pass_count += 1
    return wall_pass_count
# 主程序
if __name__ == "__main__":
    # 伪造一点示例数据
    fake_events = [
        {'player': 7, 'type': 'pass', 'x': 50, 'y': 50, 'end_x': 40, 'end_y': 50, 'time': 10.0}, # A给B
        {'player': 9, 'type': 'pass', 'x': 40, 'y': 50, 'end_x': 50, 'end_y': 48, 'time': 10.5}, # B回给A
        {'player': 7, 'type': 'pass', 'x': 50, 'y': 48, 'end_x': 60, 'end_y': 45, 'time': 11.0}  # A向前传
    ]
    count = detect_wall_pass(fake_events)
    print(f"检测到撞墙式配合次数: {count}")

使用 Pandas(进阶版,处理大型CSV文件)

如果数据量很大,用Pandas进行矢量化操作速度更快。

import pandas as pd
import numpy as np
# 假设CSV文件列名为: player_id, event_type, x, y, end_x, end_y, match_time
df = pd.read_csv('event_data.csv')
# 只保留传球事件
passes = df[df['event_type'] == 'pass'].reset_index(drop=True)
# 计算传球距离
passes['pass_dist'] = np.sqrt((passes['end_x'] - passes['x'])**2 + (passes['end_y'] - passes['y'])**2)
# 核心逻辑:利用DataFrame的shift()函数错位比较
# 找出所有连续三行传球,且间隔时间短
passes['time_gap_next'] = passes['match_time'].shift(-1) - passes['match_time']
passes['is_short_pass'] = passes['pass_dist'] < 25 # 短传
# 找到“回传”(第二次传球结束点接近第一次传球起始点)
passes['return_pass'] = ((passes['end_x'].shift(1) - passes['x']) ** 2 + 
                          (passes['end_y'].shift(1) - passes['y']) ** 2) ** 0.5 < 15
# 找到向前推进(第三次传球终结位置比第一次更靠前)
passes['forward_progress'] = passes['end_x'].shift(-2) > passes['end_x'] + 5
# 统计满足所有条件的组合
result = passes[
    (passes['is_short_pass']) &          # 第一脚是短传
    (passes['time_gap_next'] < 2) &      # 时间连续
    (passes['return_pass'].shift(1)) &   # 第二脚是回传
    (passes['forward_progress'].shift(-2)) # 第三脚向前
]
print(f"总撞墙次数: {len(result)}")

针对“视频标签”的简易脚本(适合手动打点)

如果你没有自动化数据,而是通过观看比赛录像手动标注了“传球发起点”和“传球结束点”(比如你在Excel里记录了球员A触球位置和球员B触球位置),这个脚本可以帮你计算:

# 场景:你记录了每一次触球的坐标(X,Y),以及是哪名球员
# 撞墙式配合的规则:
# 1. 3次快速触球,涉及3个球员(通常是A-B-A)
# 2. 第一次传球和第二次传球都发生在极短时间内
touch_sequence = [
    ('A', 50, 50, 10.0),  # (球员, x, y, 时间)
    ('B', 45, 48, 10.2),
    ('A', 50, 49, 10.4),
    ('C', 60, 40, 12.0),  # 这个间隔时间变长,不算
    # ... 继续记录
]
def count_wall_passes(seq, time_threshold=1.0):
    count = 0
    i = 0
    while i < len(seq) - 2:
        p1, p2, p3 = seq[i], seq[i+1], seq[i+2]
        # 判断是否是 A-B-A 模式(球员1 == 球员3 且 球员2 != 球员1)
        if p1[0] == p3[0] and p1[0] != p2[0]:
            # 判断时间是否极短
            if (p3[3] - p1[3]) < time_threshold:
                # 检查距离(球传出去又传回来)
                dist1 = ((p2[1] - p1[1])**2 + (p2[2] - p1[2])**2)**0.5
                dist2 = ((p3[1] - p2[1])**2 + (p3[2] - p2[2])**2)**0.5
                # 两次传球距离都相对短(< 30米)
                if dist1 < 30 and dist2 < 30:
                    count += 1
                    print(f"识别到撞墙: {p1[0]} -> {p2[0]} -> {p3[0]} (时间间隔: {p3[3]-p1[3]:.1f}s)")
                    i += 2  # 跳过这两次传球,避免重复计数
                    continue
        i += 1
    return count
# 使用示例
result = count_wall_passes(touch_sequence)
print(f"撞墙次数: {result}")

重要提示(撞墙”的定义)

在实际的足球数据分析中(如StatsBomb),撞墙式配合并没有一个固定的官方代码,通常分析师会使用“透视传球”(Throughball)或“连续传球次数”(Sequential Passes)来做替代统计。

如果你需要更精准的定义,可以告诉我:

  1. 你的数据源格式(是JSON、CSV还是SofaScore/WhoScored的API?)
  2. 你对“撞墙”的界定(必须是一脚出球吗?可以隔几秒吗?必须推进到对方半场吗?)

我可以为你调整脚本参数。

上一篇根据实用脚本,二过一配合成功率如何?

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

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