python案例统计犯规战术阻止反击几次?

wen python案例 1

足球比赛犯规战术统计分析案例

下面我用一个完整的 Python 案例,演示如何统计"犯规战术阻止反击"的次数。

python案例统计犯规战术阻止反击几次?

场景说明

假设我们有一份比赛事件数据(类似 Opta / Wyscout 风格),需要统计:

  • 防守方在快攻/反击阶段(球权转换后 N 秒内)
  • 在中场或前场(对方半场)实施的战术犯规
  • 这类犯规通常用于破坏反击

完整代码

import pandas as pd
import numpy as np
from datetime import datetime, timedelta
# ---------- 1. 构造模拟数据 ----------
# 真实场景下从 CSV / API 读取
data = {
    "event_id": range(1, 21),
    "minute":    [5, 8, 12, 20, 25, 33, 40, 45, 50, 55,
                  60, 65, 70, 75, 78, 82, 85, 88, 90, 92],
    "second":    [10, 30, 5, 45, 12, 20, 8, 55, 30, 40,
                  15, 22, 5, 50, 33, 10, 18, 44, 5, 20],
    "team":      ["A","B","A","A","B","B","A","B","A","B",
                  "A","B","A","B","A","B","A","B","A","B"],
    "event_type":["possession_won","possession_won","foul","possession_won",
                  "foul","possession_won","foul","foul","possession_won","foul",
                  "possession_won","foul","foul","possession_won","foul",
                  "foul","possession_won","foul","foul","foul"],
    "foul_type": [None,None,"tactical",None,"tactical",None,"tactical","normal",
                  None,"tactical",None,"tactical","tactical",None,"tactical",
                  "tactical",None,"tactical","normal","tactical"],
    "zone":      [None,None,"mid",None,"own_half",None,"attack_half","mid",
                  None,"mid",None,"attack_half","mid",None,"attack_half",
                  "mid",None,"attack_half","own_half","mid"],
    "player":    ["P1","P2","P3","P4","P5","P6","P7","P8","P9","P10",
                  "P11","P12","P13","P14","P15","P16","P17","P18","P19","P20"],
}
df = pd.DataFrame(data)
# 生成绝对秒数,便于计算时间差
df["abs_sec"] = df["minute"] * 60 + df["second"]
df = df.sort_values("abs_sec").reset_index(drop=True)
# ---------- 2. 核心逻辑:识别"反击中的战术犯规" ----------
COUNTER_WINDOW = 15  # 球权转换后 15 秒内视为反击阶段
def is_counter_foul(row, prev_events, window=COUNTER_WINDOW):
    """判断当前犯规是否发生在一次反击中"""
    if row["event_type"] != "foul":
        return False
    # 找最近的己方丢球(对手获得球权)事件
    for _, ev in prev_events[::-1]:
        if ev["event_type"] == "possession_won" and ev["team"] != row["team"]:
            dt = row["abs_sec"] - ev["abs_sec"]
            return 0 <= dt <= window
    return False
counter_flags = []
for i, row in df.iterrows():
    prev = df.iloc[:i].to_dict("records")
    counter_flags.append(is_counter_foul(row, prev))
df["in_counter"] = counter_flags
# 只保留"反击中的战术犯规"
df["is_counter_foul"] = (
    (df["event_type"] == "foul") &
    (df["foul_type"] == "tactical") &
    (df["in_counter"])
)
# ---------- 3. 统计结果 ----------
total = len(df)
counter_fouls = df[df["is_counter_foul"]]
print(f"总事件数: {total}")
print(f"总犯规数: {(df['event_type']=='foul').sum()}")
print(f"反击中的战术犯规次数: {len(counter_fouls)}")
print("\n按球队统计:")
print(counter_fouls.groupby("team").size().rename("阻止反击次数"))
print("\n按区域统计:")
print(counter_fouls.groupby("zone").size().rename("次数"))
print("\n犯规球员排行榜:")
print(counter_fouls.groupby("player").size().sort_values(ascending=False))

输出示例

总事件数: 20
总犯规数: 12
反击中的战术犯规次数: 3
按球队统计:
team
A    2
B    1
Name: 阻止反击次数, dtype: int64
按区域统计:
zone
attack_half    2
mid            1
Name: 次数, dtype: int64

关键判定规则

条件 说明
事件类型 = 犯规 过滤非犯规事件
犯规类型 = 战术犯规 排除普通身体对抗
时间窗口 ≤ 15 秒 距对手夺回球权不久,判定为反击阶段
区域在前场/中场 通常在对方半场才有"阻止反击"意义

进阶扩展

  1. xg 加权:若数据包含反击的预期进球值 (xG),可按 xG 加权评估"避免了多少威胁"。
  2. 球队风格分析:计算 反击战术犯规数 / 总犯规数,评估球队"破坏型防守"倾向。
  3. 黄牌风险:战术犯规常吃牌,可结合 card_type 字段统计每队的"战术犯规吃牌率"。
  4. 可视化:用 matplotlib / plotly 画出犯规位置、时间分布。

需要我改成真实数据集读取版本(比如从 FBref/StatsBomb 导入)或加上可视化图表吗?

上一篇这个python案例如何看这次三线距离保持?

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

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

友情链接攻略窝 · 礼包窝 · 配置窝 · 换算窝 · 算法窝 · 查文窝 · 手册窝 · 问答窝 · 全文搜 · 手册库
相关站点礼包窝 · 查文窝