本文目录导读:

- 方案一:面向“手动数据录入”的交互式统计脚本(最实用)
- 方案二:面向“视频/传感器事件流”的自动化统计脚本(处理 JSON 数据)
- 方案三:极简“文本日志”解析脚本(适合赛后快速复盘)
- 核心建议:如何定义“成功”?(决定数据有效性的关键)
要统计“高球传中争顶成功率”,首先需要明确统计口径(分母和分子),因为足球数据里没有绝对唯一的定义,通常我们理解为:
- 分母(传中总数):一次成功越过防守球员/进入禁区的传中球(或所有传中)。
- 分子(成功争顶):本方球员在禁区内抢先顶到皮球(且控制住皮球或形成射门),而非仅仅是“碰到”。
以下是针对不同场景(手动录入门将数据 / 解析比赛视频 / 处理自由文本)的三个实用脚本,使用 Python 编写。
面向“手动数据录入”的交互式统计脚本(最实用)
如果你在看比赛回放,需要手动记录每一次传中,这个脚本会实时计算成功率并保存 CSV。
import csv
import os
from datetime import datetime
# --- 配置文件 ---
CSV_FILE = "cross_win_rate.csv"
TEAM_NAME = "MyTeam" # 你的主队
# --- 初始化统计 ---
stats = {"total_crosses": 0, "successful_headers": 0, "records": []}
# 如果文件已存在,则读取历史数据(避免重复输入)
def load_existing_data():
if os.path.exists(CSV_FILE):
with open(CSV_FILE, mode='r', encoding='utf-8') as f:
reader = csv.DictReader(f)
for row in reader:
stats["records"].append(row)
stats["total_crosses"] += 1
if row["result"] in ["goal", "on_target", "controlled"]:
stats["successful_headers"] += 1
def save_record(cross_data):
"""保存单次传中记录"""
stats["records"].append(cross_data)
stats["total_crosses"] += 1
if cross_data["result"] in ["goal", "on_target", "controlled"]:
stats["successful_headers"] += 1
# 写入CSV
file_exists = os.path.isfile(CSV_FILE)
with open(CSV_FILE, mode='a', newline='', encoding='utf-8') as f:
writer = csv.DictWriter(f, fieldnames=["timestamp", "minute", "crosser", "area", "defender", "result"])
if not file_exists:
writer.writeheader()
writer.writerow(cross_data)
def calculate_rate():
if stats["total_crosses"] == 0:
return 0.0
return (stats["successful_headers"] / stats["total_crosses"]) * 100
# --- 主交互逻辑 ---
if __name__ == "__main__":
load_existing_data()
print(f"已加载历史记录 {len(stats['records'])} 条,当前成功率: {calculate_rate():.2f}%")
while True:
print("\n--- 记录新的高球传中 ---")
minute = input("比赛分钟 (65',输入 q 退出): ")
if minute.lower() == 'q':
break
crosser = input("传中球员: ")
area = input("落点区域 (前点/中路/后点): ")
# 关键:争顶结果判定
print("争顶结果分类:")
print(" 1. 成功-进球 (goal)")
print(" 2. 成功-射正 (on_target)")
print(" 3. 成功-控制住球 (controlled)")
print(" 4. 失败-顶偏 (miss)")
print(" 5. 失败-被解围 (cleared)")
result_choice = input("选择结果 (1-5): ")
result_map = {
"1": "goal", "2": "on_target",
"3": "controlled", "4": "miss", "5": "cleared"
}
result = result_map.get(result_choice, "miss")
record = {
"timestamp": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"minute": minute,
"crosser": crosser,
"area": area,
"defender": "", # 可扩展
"result": result
}
save_record(record)
print(f"记录完成!当前成功率: {calculate_rate():.2f}% ({stats['successful_headers']}/{stats['total_crosses']})")
使用方法:python script.py 即可。
面向“视频/传感器事件流”的自动化统计脚本(处理 JSON 数据)
假如你从录像分析软件(如 LongoMatch、SportsCode)或 AI 模型导出了事件流数据,数据格式类似 [{event: 'cross', ...}, {event: 'header', ...}]。
import json
from collections import defaultdict
def analyze_cross_headers(data_file):
"""
解析包含 'cross' 和 'header' 事件的 JSON 文件。
假设事件格式:
{"type": "cross", "team": "A", "player": 10, "minute": 30, "outcome": "completed"}
{"type": "header", "team": "A", "player": 9, "minute": 30, "outcome": "target"}
"""
with open(data_file, 'r', encoding='utf-8') as f:
events = json.load(f)
# 统计字典
cross_events = [] # 存储所有传中
# 1. 筛选出所有传中事件(视为分母)
for event in events:
if event.get('type') == 'cross' and event.get('team') == 'MyTeam':
cross_events.append(event)
# 2. 筛选出争顶成功事件(分子)
# 需要定义“成功”:要么紧接着出现了 header 事件,要么 cross 本身造成了威胁
success_count = 0
for cross in cross_events:
cross_minute = cross.get('minute')
cross_id = cross.get('id')
# 查找同一分钟内(或接下来几秒)是否有 header 事件
# 简化逻辑:寻找同队、同分钟,且时间戳紧随其后的 header 事件
for event in events:
if event.get('type') == 'header' and event.get('team') == 'MyTeam':
if event.get('minute') == cross_minute and event.get('id') != cross_id:
# 判定标准:header 的 outcome 为 target 或 goal
if event.get('outcome') in ['target', 'goal', 'controlled']:
success_count += 1
break # 一次传中只算一次成功
total = len(cross_events)
success_rate = (success_count / total * 100) if total > 0 else 0
print(f"总传中数: {total}")
print(f"成功争顶数: {success_count}")
print(f"高球争顶成功率: {success_rate:.2f}%")
# 按区域分析(可选)
area_stats = defaultdict(lambda: [0, 0])
for cross in cross_events:
area = cross.get('area', 'unknown')
area_stats[area][0] += 1
# 在此处简化处理,实际需要关联 header 事件
# area_stats[area][1] += 是否成功...
return success_rate
# 调用示例
# analyze_cross_headers("match_events.json")
极简“文本日志”解析脚本(适合赛后快速复盘)
如果你只是把比赛中的关键事件通过文字记录下来,这个脚本能快速统计。
输入格式(文本文件 log.txt):
45' 传中 左边路 落点:前点 结果:成功
55' 传中 右边路 落点:中路 结果:失败
60' 传中 左边路 落点:后点 结果:成功-进球
import re
def parse_text_log(filepath):
success_keywords = ['成功', '进球', '射正', '控住']
total = 0
success = 0
with open(filepath, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if not line or '传中' not in line:
continue
# 判断是否为成功(简单关键词匹配)
# 可以在这里扩展更复杂的正则规则
if any(keyword in line for keyword in success_keywords):
success += 1
total += 1
rate = (success / total * 100) if total > 0 else 0
print(f"解析到 {total} 次传中,成功 {success} 次,成功率 {rate:.2f}%")
# 进阶:用正则提取区域
area_pattern = r'落点:(\S+)'
area_success = {}
for line in open(filepath, encoding='utf-8'):
match = re.search(area_pattern, line)
if match and '传中' in line:
area = match.group(1)
# ... 此处省略具体的累计逻辑
if __name__ == "__main__":
parse_text_log("log.txt")
核心建议:如何定义“成功”?(决定数据有效性的关键)
在使用上述脚本前,建议先定好你的球队战术手册的标准:
- 严格定义(推荐):只有本方球员在对方禁区内抢先顶到球,并且皮球飞向球门方向(射正/进球)或回做给队友形成二次进攻,才记为“成功”。
- 宽松定义:只要顶到皮球(无论顶去哪)都算成功,这种定义下成功率通常会很高(70%+),但参考价值有限。
- 考虑“竞争性”:如果挑战性的“顶球”对手是空位或者无人防守,一般不计入统计。
如果没有 Python 环境,可以直接用 Excel 或笔记应用,按照这个公式自行计算:
[ 成功率(\%) = \frac{\text{积极争顶成功次数(顶到+控制住/射门)}}{\text{总传中次数(球进入本方进攻三区且有机会争顶)}} ]
你可以根据手头数据的格式(是手动输入、JSON 还是纯文本),选择最合适的一个脚本来用,如果需要调整匹配逻辑(比如只看头球攻门、只看特定球员),可以在评论区告诉我具体需求。