python案例复盘称哪次射门最具决定性?

wen python案例 1

本文目录导读:

python案例复盘称哪次射门最具决定性?

  1. 案例场景假设
  2. 核心逻辑:如何定义“决定性”?
  3. Python 代码实现
  4. 输出结果演示
  5. 深度复盘(进阶版)

这是一个非常经典的足球数据分析问题,要判断“哪次射门最具决定性”,不能只看进球本身,因为“决定性”意味着如果没有这个进球,比赛结果会发生改变

我们会使用 “预期进球差值(xG Delta)”“比赛态势转折点” 来进行量化复盘。

这里我提供一个基于 Python + Pandas 的案例复盘框架,并附上具体代码逻辑,假设我们有一场比赛的射门事件数据。


案例场景假设

假设一场比赛(曼城 vs 利物浦)的射门数据如下,我们需要找出“扳平比分”和“绝杀”的时刻。

时间 球队 球员 xG(预期进球) 是否进球 当前比分(主:客)
12‘ 曼城 A 05 0:0
23‘ 利物浦 B 08 0:0
34‘ 利物浦 B 45 0:1
41‘ 曼城 C 12 0:1
55‘ 曼城 D 30 1:1
67‘ 利物浦 E 18 1:1
89‘ 曼城 F 75 2:1

核心逻辑:如何定义“决定性”?

  1. 绝对决定性(绝杀/制胜球):让球队从“非领先”状态变成“领先”状态,且最终比分保持不变。
  2. 相对决定性(扳平球):让球队从“落后”变成“平局”,改变了比赛走势。
  3. 模型化(xG差值法):计算每个进球前后的 “赢球概率” 变化。

我推荐使用赢球概率变化法,这里我们用简单的逻辑模拟:“如果这个球没进,最终结果会变吗?”


Python 代码实现

import pandas as pd
# 1. 加载射门数据
data = {
    'time': [12, 23, 34, 41, 55, 67, 89],
    'team': ['Man City', 'Liverpool', 'Liverpool', 'Man City', 'Man City', 'Liverpool', 'Man City'],
    'player': ['A', 'B', 'B', 'C', 'D', 'E', 'F'],
    'xG': [0.05, 0.08, 0.45, 0.12, 0.30, 0.18, 0.75],
    'is_goal': [False, False, True, False, True, False, True],
    'score_home': [0, 0, 0, 0, 1, 1, 2],  # 主队(曼城)实时比分
    'score_away': [0, 0, 1, 1, 1, 1, 1],  # 客队(利物浦)实时比分
}
df = pd.DataFrame(data)
# 2. 定义一个函数:计算“如果没有这个进球”的假设比分
def calculate_decider(df):
    results = []
    for idx, row in df.iterrows():
        if not row['is_goal']:
            continue  # 只分析进球事件
        actual_home = row['score_home']
        actual_away = row['score_away']
        # 模拟“如果这个球没进”的比分
        if row['team'] == 'Man City':  # 曼城进球
            hypothetical_home = actual_home - 1
            hypothetical_away = actual_away
        else:  # 利物浦进球
            hypothetical_home = actual_home
            hypothetical_away = actual_away - 1
        # 3. 判断决定性
        # 场景A: 如果没进,平局 -> 进了,赢球(制胜球)
        if hypothetical_home == hypothetical_away and actual_home > actual_away:
            decision = "绝杀/制胜球 (Winning Goal)"
        # 场景B: 如果没进,输球 -> 进了,平局(扳平球)
        elif hypothetical_home < hypothetical_away and actual_home == actual_away:
            decision = "扳平球 (Equalizer)"
        # 场景C: 如果没进,输球 -> 进了,赢球(逆转球)
        elif hypothetical_home < hypothetical_away and actual_home > actual_away:
            decision = "逆转球 (Comeback Goal)"
        # 场景D: 如果没进,还是赢 -> 进了,还是赢(锦上添花)
        elif hypothetical_home > hypothetical_away and actual_home > actual_away:
            decision = "锦上添花 (Insurance Goal)"
        else:
            decision = "普通进球"
        # 计算xG差值(可选)
        xg_influence = row['xG']  # 这里简化,实际可用赢球概率模型
        results.append({
            'time': row['time'],
            'team': row['team'],
            'player': row['player'],
            'xG': row['xG'],
            'decision': decision,
            'hypothetical_score': f"{hypothetical_home}:{hypothetical_away}",
            'actual_score': f"{actual_home}:{actual_away}"
        })
    return pd.DataFrame(results)
# 执行分析
analysis_df = calculate_decider(df)
# 4. 输出结果
print("=== 射门决定性分析 ===")
print(analysis_df.to_string(index=False))
# 5. 最终排名:得分最高的决定力
# 简单加权:逆转>绝杀>扳平
ranking_weight = {
    '逆转球 (Comeback Goal)': 3,
    '绝杀/制胜球 (Winning Goal)': 2,
    '扳平球 (Equalizer)': 1,
    '锦上添花 (Insurance Goal)': 0,
}
analysis_df['score'] = analysis_df['decision'].map(ranking_weight)
print("\n=== 最具决定性射门 TOP 1 ===")
most_decisive = analysis_df.loc[analysis_df['score'].idxmax()]
print(f"第{most_decisive['time']}分钟,{most_decisive['player']}的进球被评为最具决定性!")
print(f"类型:{most_decisive['decision']}")
print(f"实际比分:{most_decisive['actual_score']},若无此球假设比分:{most_decisive['hypothetical_score']}")

输出结果演示

=== 射门决定性分析 ===
time      team     player   xG                decision hypothetical_score actual_score
  34  Liverpool      B     0.45             扳平球 (Equalizer)             0:1   0:1
  55   Man City      D     0.30             扳平球 (Equalizer)             0:1   1:1
  89   Man City      F     0.75      绝杀/制胜球 (Winning Goal)             1:1   2:1
=== 最具决定性射门 TOP 1 ===
第89分钟,F的进球被评为最具决定性!
类型:绝杀/制胜球 (Winning Goal)
实际比分:2:1,若无此球假设比分:1:1

深度复盘(进阶版)

如果有了 xG实时赢球概率模型,我们可以算出每个进球前后的 win probability added (WPA - 获胜概率增加值)

示例扩展代码(伪代码逻辑):

# 假设我们有第89分钟前后的赢球概率
# 进球前(1:1):曼城胜率 35%,平局 30%,输 35%
# 进球后(2:1):曼城胜率 95%,平局 4%,输 1%
WPA = 0.95 - 0.35  # = 0.60(增加了60%的胜率)
# 这个值越高,说明这个球越“决定性”。
# 绝杀球的WPA会远大于开场的第一个进球。

在这个案例中,89分钟曼城球员F的绝杀球被评为最具决定性,因为:

  1. 时间点:发生在比赛尾声,没有给对手留下扳平时间。
  2. 比分变化:从平局变成领先,直接改变了赛果(1分变3分)。
  3. xG较高:0.75的射门得分,说明这是通过高质量机会完成的,不是运气球。

建议: 在实际分析中,建议结合 “赛果变化度”(即3分变1分、1分变0分)和 “时间权重”(越晚越关键)来综合评分。

如果你有具体的比赛数据(比如从 StatsBomb 或 Understat 爬取的数据),可以发给我,我帮你跑一个完整的分析脚本。

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