实用脚本统计犯规战术阻止反击几次?

wen 实用脚本 6

足球犯规战术阻止反击统计脚本

下面给你一个可直接运行的 Python 脚本,用来统计一场比赛中「犯规战术阻止反击」的次数,核心思路是:用事件数据(坐标、时间、犯规类型、是否快攻/反击)来识别“战术犯规”场景。

实用脚本统计犯规战术阻止反击几次?


判定逻辑

一次犯规被计为「战术犯规阻止反击」需同时满足:

  1. 事件类型 = 犯规(Foul)
  2. 犯规发生在防守方半场或中场(阻止对方推进)
  3. 犯规前对方处于反击/快攻状态(由数据字段 is_counter_attack 或通过时间+位移推断)
  4. 犯规者未得球(非抢断失败),且裁判未判点球
  5. 可选:犯规后对方进攻被中断(下一事件不是射门/进球)

脚本(Python + pandas)

import pandas as pd
# ============ 1. 读取事件数据 ============
# 假设 CSV 列: match_id, minute, second, team, player, event_type,
#              x, y, is_counter_attack, foul_type, card, outcome
df = pd.read_csv("events.csv")
# ============ 2. 参数配置 ============
COUNTER_WINDOW_SEC = 8      # 反击判定时间窗(秒)
DEFENSIVE_HALF_X = 60       # 防守方半场 x 阈值(0-100 坐标系,进攻方向向右)
EXCLUDE_FOUL_TYPES = {"penalty"}  # 排除点球犯规
def to_seconds(row):
    return row["minute"] * 60 + row["second"]
df["t"] = df.apply(to_seconds, axis=1)
df = df.sort_values(["match_id", "t"]).reset_index(drop=True)
# ============ 3. 标记“反击状态” ============
# 若数据自带 is_counter_attack 字段直接用;否则用规则推断:
# 犯规前 COUNTER_WINDOW_SEC 秒内,对方在本方半场快速向前推进(x 增幅 > 15)
def mark_counter(df):
    df["counter_flag"] = df.get("is_counter_attack", 0).fillna(0).astype(int)
    if "is_counter_attack" not in df.columns:
        for i in range(1, len(df)):
            prev, cur = df.iloc[i-1], df.iloc[i]
            if cur["team"] != prev["team"]:
                dt = cur["t"] - prev["t"]
                dx = cur["x"] - prev["x"]
                if 0 < dt <= COUNTER_WINDOW_SEC and dx > 15:
                    df.at[i, "counter_flag"] = 1
    return df
df = mark_counter(df)
# ============ 4. 识别战术犯规阻止反击 ============
def is_tactical_counter_foul(row, prev_row):
    if row["event_type"] != "Foul":
        return False
    if row.get("foul_type") in EXCLUDE_FOUL_TYPES:
        return False
    if row.get("card") == "penalty":
        return False
    # 犯规发生在防守方半场(进攻方向向右,防守方在本方 x<50 区域)
    if row["x"] > DEFENSIVE_HALF_X:
        return False
    # 犯规前对方处于反击状态
    if prev_row is None or prev_row["team"] == row["team"]:
        return False
    if prev_row["counter_flag"] != 1 and row["counter_flag"] != 1:
        return False
    return True
results = []
for i in range(1, len(df)):
    cur, prev = df.iloc[i], df.iloc[i-1]
    if is_tactical_counter_foul(cur, prev):
        results.append({
            "match_id": cur["match_id"],
            "minute": cur["minute"],
            "second": cur["second"],
            "team": cur["team"],
            "player": cur["player"],
            "x": cur["x"],
            "y": cur["y"],
            "foul_type": cur.get("foul_type"),
            "card": cur.get("card"),
        })
tactical_df = pd.DataFrame(results)
# ============ 5. 输出统计 ============
print(f"总战术犯规阻止反击次数: {len(tactical_df)}")
if not tactical_df.empty:
    print("\n按球队统计:")
    print(tactical_df.groupby("team").size().sort_values(ascending=False))
    print("\n按球员统计 (Top 10):")
    print(tactical_df.groupby(["team", "player"]).size()
          .sort_values(ascending=False).head(10))
tactical_df.to_csv("tactical_counter_fouls.csv", index=False)
print("\n明细已保存到 tactical_counter_fouls.csv")

数据字段要求

字段 说明 是否必需
match_id 比赛 ID
minute / second 事件时间
team / player 犯规方
event_type 事件类型(Foul / Pass / Shot…)
x / y 场地坐标(0–100)
is_counter_attack 是否反击(0/1) ⭕ 可选,无则脚本推断
foul_type 犯规类型
card 牌 / 是否点球

如何校准

  1. COUNTER_WINDOW_SEC:默认 8 秒,反击节奏快的联赛可调到 5–6 秒。
  2. DEFENSIVE_HALF_X:默认 60(即本方半场 0–60),可按坐标系调整。
  3. dx > 15:反击推进阈值,可根据联赛平均推进速度调整。
  4. 若有 StatsBomb / Opta / Wyscout 数据,直接使用其 counter_attack 标签更准确。

扩展建议

  • 加入 “犯规后进攻是否中断” 判断:检查犯规后 10 秒内对方是否射门,若射门则可能不算“成功阻止”。
  • 区分 “战术犯规吃牌” 与 “普通犯规”:card in {Yellow, Red} 可作为战术犯规的强信号。
  • 输出 热力图:用 matplotlib 画出犯规位置分布。

需要我帮你把脚本适配到 StatsBomb 开源数据 或 Wyscout 格式,或者加上可视化热力图吗?

上一篇这个实用脚本显示体能消耗数据差异?

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

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