实用脚本统计界外球进攻威胁次数?

wen 实用脚本 6

本文目录导读:

实用脚本统计界外球进攻威胁次数?

  1. 方案一:基础版(基于事件标签统计)
  2. 方案二:进阶版(基于坐标的AI威胁判定)
  3. 如何调整成你的实际数据?
  4. 需要进一步帮助?

根据你的需求,我为你准备了一个足球战术分析脚本,用于统计“界外球进攻威胁次数”。

⚠️ 重要提示:由于“威胁”是主观定义,我提供了两种统计模式(基础传球模式 & 智能威胁模式),你可以根据视频/图表数据源的详细程度来选择。


  1. 数据输入:支持从 CSV 文件读取事件数据(时间戳、球员、动作类型、坐标)。
  2. 统计维度
    • 总界外球次数。
    • 形成“有效进攻”的次数(至少完成一次成功传接)。
    • 进攻三区(危险区域) 触球次数。
    • 最终形成射门 / 绝佳机会(Big Chance)的次数。
  3. 输出:控制台打印统计报告 + 生成可视化热力图(可选)。

基础版(基于事件标签统计)

适用于:你有包含 Throw-in(界外球)、Pass(传球)、Shot(射门)等标签的 XML/CSV 数据。

import csv
from collections import defaultdict
def analyze_throw_in_threats(file_path):
    """
    统计界外球进攻威胁
    :param file_path: CSV文件路径,需包含列:event_type, start_x, start_y, end_x, end_y, outcome, team
    """
    # 1. 数据加载与筛选
    throw_ins = []
    passes = []
    shots = []
    with open(file_path, 'r', encoding='utf-8') as f:
        reader = csv.DictReader(f)
        for row in reader:
            event = row['event_type']
            if event == 'Throw-in':
                throw_ins.append(row)
            elif event == 'Pass' and row['outcome'] == 'Successful':
                passes.append(row)
            elif event == 'Shot' or event == 'Attempt':
                shots.append(row)
    # 2. 分析阶段:追踪每次界外球的后续串联
    threats = []
    for t in throw_ins:
        # 找该界外球的球队和对位
        team = t['team']
        start_loc = (float(t['start_x']), float(t['start_y']))
        # 模拟:在接下来的5个事件内寻找该队的有效进攻
        threat_chain = {
            'total': 1,
            'possession_starts': 0,
            'danger_area_touches': 0,
            'shots_generated': 0
        }
        # 实际逻辑需根据数据时间顺序关联,这里简化示例
        # 找出紧随其后的5个该队事件
        # ... (这里需要关联你的数据)
        # 危险区域判定:假设对方半场 罚球区(18码) 定义为 X>75
        if start_loc[0] > 75:
            threat_chain['danger_area_touches'] += 1
        threats.append(threat_chain)
    # 3. 输出统计报表
    total_throws = len(throw_ins)
    danger_touches = sum(t['danger_area_touches'] for t in threats)
    shot_from_throw = sum(1 for s in shots if s['team'] in [t['team'] for t in throw_ins] and float(s['start_x']) > 75)
    print(f"===== 界外球进攻威胁统计 =====")
    print(f"总界外球数: {total_throws}")
    print(f"形成进攻三区触球: {danger_touches} 次")
    print(f"由界外球策动的射门: {shot_from_throw} 次")
    print(f"界外球转化射门率: {shot_from_throw/total_throws*100:.1f}%")
    return threats
# 使用示例
# analyze_throw_in_threats('match_events.csv')

进阶版(基于坐标的AI威胁判定)

适用于:你有球员位置追踪数据,需要计算“实际渗透力”。

该脚本使用 “界外球后5秒内,球在对方禁区前的推进距离” 作为威胁指数。

import math
import statistics
class ThrowInAnalyst:
    def __init__(self):
        self.throw_in_events = []
        self.pass_sequences = []
    def add_throw_in(self, time, team, x, y):
        """记录界外球事件"""
        self.throw_in_events.append({
            'time': time, 
            'team': team, 
            'x': x, 
            'y': y
        })
    def add_pass(self, time, team, start_x, start_y, end_x, end_y, successful=True):
        """记录传球事件"""
        self.pass_sequences.append({
            'time': time,
            'team': team,
            'start': (start_x, start_y),
            'end': (end_x, end_y),
            'successful': successful
        })
    def calculate_threat_score(self, throw_x, throw_y, team_passes):
        """
        计算威胁指数 (0-100)
        指标: 距离目标(对方球门) | 传球推进速度 | 射门机会点
        """
        # 假设对方球门在 (100, 50) 基于半场坐标
        goal_x, goal_y = 100, 50
        distance_to_goal = math.sqrt((goal_x - throw_x)**2 + (goal_y - throw_y)**2)
        # 威胁评分:越接近球门=分数越高
        distance_score = max(0, (100 - distance_to_goal) / 100) * 50
        # 传球深度推进
        total_progression = 0
        for p in team_passes[:3]:  # 取前3次传球
            dx = p[1][0] - p[0][0]
            total_progression += dx
        progression_score = min(50, total_progression * 2)
        return distance_score + progression_score
    def analyze(self):
        """主分析逻辑"""
        stats = {
            'total': len(self.throw_in_events),
            'threats_high': 0,   # 威胁>60
            'threats_med': 0,    # 威胁 30-60
            'threats_low': 0,    # 威胁<30
            'avg_threat': 0
        }
        threat_list = []
        for idx, throw_in in enumerate(self.throw_in_events):
            # 查找与该界外球时间相近的该队传球 (简化: 取后续3次)
            team_passes = []
            for p in self.pass_sequences:
                if p['time'] > throw_in['time'] and p['team'] == throw_in['team']:
                    team_passes.append(p)
                    if len(team_passes) == 3:
                        break
            # 计算威胁值
            threat_value = self.calculate_threat_score(
                throw_in['x'], throw_in['y'], team_passes
            )
            threat_list.append(threat_value)
            # 分级
            if threat_value > 60:
                stats['threats_high'] += 1
            elif threat_value > 30:
                stats['threats_med'] += 1
            else:
                stats['threats_low'] += 1
        # 清空列表后重新建立当前动态的统计结果
        stats['avg_threat'] = statistics.mean(threat_list) if threat_list else 0
        print("\n" + "="*50)
        print("  界外球进攻威胁分析报告")
        print("="*50)
        print(f" 总界外球数: {stats['total']}")
        print(f" 高威胁次数 (>60分): {stats['threats_high']}次")
        print(f" 中威胁次数 (30-60分): {stats['threats_med']}次")
        print(f" 低威胁次数 (<30分): {stats['threats_low']}次")
        print(f" 平均威胁指数: {stats['avg_threat']:.1f}/100")
        print("="*50)
        # 返回可进一步处理的数据
        return stats, threat_list
# 示例测试数据
if __name__ == "__main__":
    analyst = ThrowInAnalyst()
    # 模拟数据:第10分钟 左侧边界抛球,之后有两次有威胁的传球
    analyst.add_throw_in(600, "Home", 30, 75)  # 本方半场界外球
    analyst.add_pass(602, "Home", 30, 75, 45, 80, True)
    analyst.add_pass(605, "Home", 45, 80, 70, 85, True)  # 推进至对方危险区
    analyst.add_pass(608, "Home", 70, 85, 95, 88, True)  # 传入禁区
    analyst.add_throw_in(700, "Home", 85, 50)  # 对方半场靠近边界
    analyst.add_pass(702, "Home", 85, 50, 90, 80, True)
    analyst.analyze()

如何调整成你的实际数据?

  1. 如果数据在 Excel:导出为 CSV,修改方案一的字段名。
  2. 如果数据是视频分析:使用 Opta/StatsBomb 等平台导出事件数据,将 event_type 对应为 throw-inpassshot
  3. 自定义“威胁”定义:在 calculate_threat_score 函数中,你可以增加“是否直入禁区”判断,或加入“控球时间”作为权重。

需要进一步帮助?

如果你能提供 数据样本格式(哪怕是几行),我可以帮你定制一个完全匹配的脚本,比如你的数据是长这样?:

时间 事件 球员 起始 x 起始 y 结束 x 结束 y 结果
45:30 Throw-in 10号 25 40 成功

告诉我你的具体数据格式,我可以直接帮你写一个开箱即用的版本。

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