这个实用脚本显示横传转移球次数?

wen 实用脚本 9

本文目录导读:

这个实用脚本显示横传转移球次数?

  1. 脚本逻辑(核心算法)
  2. 通用 Python 脚本
  3. 如何调整以适配你的具体需求
  4. 预测(可能是你们期望的另一种情况)

要为足球比赛分析显示“横传转移球”次数,我们需要先明确一个技术统计的定义:

横传转移球(Switch of Play / Square Pass):通常指球权在球场宽度上的大范围转移(通常是从一侧边路转移到另一侧边路),目的是改变进攻方向,但也有很多分析视频将“所有横向传球”都统计在内。

由于你没有指定是哪款足球游戏(如 FIFA/FC、实况足球)或哪款分析软件(如 DataVolley、Sportscode),我将为你提供一个通用的 Python 示例脚本

这个脚本的思路是:基于球员传球的坐标数据,计算每次传球的角度和距离,并判断是否为“横传转移”。


脚本逻辑(核心算法)

  1. 输入数据:假设你有一个包含传球数据的 CSV 文件(包含传球起点 X1, Y1 和终点 X2, Y2 坐标)。
  2. 判断标准(通常的标准):
    • 角度:传球方向与球场长边(X轴)的夹角大于 45 度(即主要是横向移动)。
    • 距离:传球距离超过一定阈值(25 米),排除短距离横传配合。
  3. 输出:打印横传转移球的次数。

通用 Python 脚本

import csv
import math
def is_switch_of_play(pass_data, angle_threshold=45, distance_threshold=25):
    """
    判断单次传球是否为“横传转移球”。
    参数:
    - pass_data: 包含 x1, y1, x2, y2 的字典或列表
    - angle_threshold: 与水平线的夹角阈值(度),默认45度
    - distance_threshold: 最小传球距离(米/单位),默认25单位
    返回:
    - bool: 是否为横传转移球
    """
    # 计算坐标差值(假设球场坐标系)
    dx = pass_data['x2'] - pass_data['x1']
    dy = abs(pass_data['y2'] - pass_data['y1'])  # 横向移动距离(宽)
    # 计算传球绝对距离
    distance = math.sqrt(dx**2 + dy**2)
    # 计算与 X 轴(纵向推进方向)的夹角
    # 防呆处理:dx 为 0,角度为 90度(纯横向)
    if dx == 0:
        angle = 90.0
    else:
        # 计算角度(相对于垂直方向)
        # 这里使用 atan2(dy, dx),并取绝对值
        angle = abs(math.degrees(math.atan2(dy, dx)))
    # 判断逻辑:
    # 1. 角度 > 阈值:说明是横向传球(而非向前传球)
    # 2. 距离 > 阈值:说明是大范围转移(而非普通短传)
    if angle >= angle_threshold and distance >= distance_threshold:
        return True
    else:
        return False
def analyze_passes_from_csv(filepath):
    """
    从 CSV 文件读取传球数据,统计横传转移球次数。
    CSV 格式要求:
    - 必须有列名:x1, y1, x2, y2
    - 坐标单位可以是米或任意单位(如果球场长度为100)
    """
    switch_count = 0
    total_passes = 0
    try:
        with open(filepath, mode='r', encoding='utf-8') as file:
            reader = csv.DictReader(file)
            for row in reader:
                total_passes += 1
                # 转换为浮点数
                pass_data = {
                    'x1': float(row['x1']),
                    'y1': float(row['y1']),
                    'x2': float(row['x2']),
                    'y2': float(row['y2'])
                }
                if is_switch_of_play(pass_data):
                    switch_count += 1
                    # 打印这条有效的转移球
                    print(f"[转移球] 传球 #{total_passes}: 从 ({pass_data['x1']:.1f}, {pass_data['y1']:.1f}) 到 ({pass_data['x2']:.1f}, {pass_data['y2']:.1f})")
        print("\n" + "="*40)
        print(f"总传球次数: {total_passes}")
        print(f"横传转移球次数: {switch_count}")
        print(f"转移球占比: {switch_count/total_passes:.2%}" if total_passes > 0 else "无数据")
    except FileNotFoundError:
        print(f"错误: 文件 {filepath} 未找到。")
    except KeyError as e:
        print(f"错误: CSV 文件中缺少必要的列 {e}")
    except Exception as e:
        print(f"发生未知错误: {e}")
# --- 使用示例 ---
# 1. 创建模拟数据(如果你想测试,可以复制以下代码到文件里运行)
if __name__ == "__main__":
    # 创建一个测试 CSV 文件(示例数据)
    sample_data = """x1,y1,x2,y2\n10,10,15,12\n10,10,80,12\n20,20,25,22\n5,40,90,45\n50,50,52,55"""
    test_file = "sample_passes.csv"
    with open(test_file, "w") as f:
        f.write(sample_data)
    print("--- 正在分析示例数据 ---")
    print("数据说明:第二组 (10,10)->(80,12),第四组 (5,40)->(90,45) 应该是转移球")
    print("\n分析结果:")
    analyze_passes_from_csv(test_file)
    # 删除临时文件
    import os
    os.remove(test_file)

如何调整以适配你的具体需求

如果你有特定的数据源,请参考以下调整方式:

  1. 如果你使用的是“坐标轴相反”的数据(如 0-100 为 X 轴代表宽度,0-68 为 Y 轴代表高度):

    • 修改 dxdy 的定义,确保 dy 代表球场的长边移动距离,dx 代表宽度。
    • 修改角度计算的基准轴。
  2. 如果你使用的是视频分析软件(如 Sportscode)

    • 需要将该软件导出的 .xml 或有特定格式的数据进行解析,提取出坐标字段即可。
  3. 如果你只需要“某一侧”的转移(比如左后卫转移到右边锋):

    可以添加代码,检查传球起点的Y坐标和传球终点的Y坐标方向。


预测(可能是你们期望的另一种情况)

如果你想要的是一个能直接看的 Web 界面/实况显示(比如在 Obsidian 或 Grafana 中实时显示),那通常是调用 API,如果你能告诉我你具体的数据来源想运行的平台(Python/Jupyter/Excel/网页),我可以为你定制一个更精准的“实用脚本”。

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