python案例统计马赛回旋使用频率如何?

wen python案例 3

统计"马赛回旋"使用频率的 Python 案例

"马赛回旋"(Marseille Turn / Roulette)是足球中齐达内的标志性过人动作,下面我给出一个完整可运行的 Python 案例,模拟从比赛事件数据中统计马赛回旋的使用频率。

python案例统计马赛回旋使用频率如何?

项目背景

假设你有一份足球比赛事件记录数据(类似 StatsBomb、Opta 格式),需要统计:

  • 每场比赛马赛回旋使用次数
  • 每名球员使用频率
  • 球队层面统计
  • 使用成功率

数据准备(模拟数据)

import pandas as pd
import numpy as np
from collections import Counter
# 模拟比赛事件数据
np.random.seed(42)
players = {
    "Messi": "Inter Miami",
    "Zidane": "Real Madrid",
    "Neymar": "Al Hilal",
    "Mbappe": "Real Madrid",
    "Bellingham": "Real Madrid",
    "Vinicius": "Real Madrid",
    "Musiala": "Bayern",
    "Kvaratskhelia": "PSG",
}
events = []
match_ids = [f"M{i:03d}" for i in range(1, 11)]  # 10场比赛
for match in match_ids:
    for player, team in players.items():
        # 每场该球员的过人事件数(泊松分布)
        n_dribbles = np.random.poisson(6)
        for _ in range(n_dribbles):
            # 5% 概率是马赛回旋
            is_marseille = np.random.random() < 0.05
            success = np.random.random() < (0.75 if is_marseille else 0.6)
            events.append({
                "match_id": match,
                "player": player,
                "team": team,
                "event_type": "Marseille Turn" if is_marseille else "Other Dribble",
                "success": success,
                "minute": np.random.randint(1, 91),
            })
df = pd.DataFrame(events)
print(f"总事件数: {len(df)}")
print(df.head())

核心统计分析

# 1. 全局使用频率
total_dribbles = df[df["event_type"].isin(["Marseille Turn", "Other Dribble"])].shape[0]
marseille_count = df[df["event_type"] == "Marseille Turn"].shape[0]
global_rate = marseille_count / total_dribbles
print(f"\n【全局统计】")
print(f"所有过人事件: {total_dribbles}")
print(f"马赛回旋次数: {marseille_count}")
print(f"使用频率: {global_rate:.2%}")
# 2. 按球员统计
player_stats = df.groupby("player").agg(
    total_dribbles=("event_type", "size"),
    marseille_count=("event_type", lambda x: (x == "Marseille Turn").sum()),
    marseille_success=(
        "success",
        lambda x: df.loc[x.index][df.loc[x.index, "event_type"] == "Marseille Turn"]["success"].sum()
    ),
)
# 修正:更清晰的写法
player_stats = df.groupby("player").apply(
    lambda g: pd.Series({
        "总过人": len(g),
        "马赛回旋次数": (g["event_type"] == "Marseille Turn").sum(),
        "使用频率": (g["event_type"] == "Marseille Turn").mean(),
        "成功率": g[g["event_type"] == "Marseille Turn"]["success"].mean()
                  if (g["event_type"] == "Marseille Turn").sum() > 0 else np.nan,
    }),
    include_groups=False
).sort_values("马赛回旋次数", ascending=False)
print("\n【球员统计】")
print(player_stats.round(3))
# 3. 球队层面统计
team_stats = df.groupby("team").agg(
    总过人=("event_type", "size"),
    马赛回旋次数=("event_type", lambda x: (x == "Marseille Turn").sum()),
).assign(使用频率=lambda x: x["马赛回旋次数"] / x["总过人"])
team_stats = team_stats.sort_values("使用频率", ascending=False)
print("\n【球队统计】")
print(team_stats.round(3))
# 4. 按比赛统计
match_stats = df.groupby("match_id").agg(
    马赛回旋次数=("event_type", lambda x: (x == "Marseille Turn").sum()),
    总事件=("event_type", "size"),
)
match_stats["场均频率"] = match_stats["马赛回旋次数"] / match_stats["总事件"]
print("\n【各场比赛统计】")
print(match_stats.round(3))

可视化

import matplotlib.pyplot as plt
import matplotlib as mpl
# 中文字体设置
mpl.rcParams["font.sans-serif"] = ["SimHei", "Microsoft YaHei", "Arial Unicode MS"]
mpl.rcParams["axes.unicode_minus"] = False
fig, axes = plt.subplots(1, 2, figsize=(14, 5))
# 左图:球员马赛回旋次数
player_stats["马赛回旋次数"].plot(
    kind="barh", ax=axes[0], color="steelblue"
)
axes[0].set_title("各球员马赛回旋使用次数")
axes[0].set_xlabel("次数")
axes[0].invert_yaxis()
# 右图:球员使用频率
player_stats["使用频率"].sort_values().plot(
    kind="barh", ax=axes[1], color="coral"
)
axes[1].set_title("各球员马赛回旋使用频率(占个人过人比例)")
axes[1].set_xlabel("频率")
axes[1].xaxis.set_major_formatter(mpl.ticker.PercentFormatter(xmax=1))
plt.tight_layout()
plt.savefig("marseille_turn_stats.png", dpi=150)
plt.show()

关键指标解读

指标 含义 合理区间
全局使用频率 马赛回旋占所有过人比例 3%–8%
球员使用频率 该球员的偏好程度 0%–15%
成功率 马赛回旋成功完成比例 60%–80%
场均次数 每场平均使用 1–3 次

接入真实数据的建议

如果你有真实数据源,只需替换 df 的构造部分:

# StatsBomb 示例(需要安装 statsbombpy)
from statsbombpy import sb
events = sb.events(match_id=3788741)
df = events[events["type"] == "Dribble"].copy()
df["event_type"] = df["dribble_type"].apply(
    lambda x: "Marseille Turn" if x == "Roulette" else "Other Dribble"
)

StatsBomb 中马赛回旋被标记为 dribble_type = "Roulette" 或 "Nutmeg"(需区分)。

可扩展方向

  1. 时空分析:马赛回旋发生在哪个区域(进攻三区占比)
  2. 比赛状态:领先/落后时的使用差异
  3. 对手强度:面对强队是否更常用
  4. 组合统计:马赛回旋后是否创造射门/进球(xT 值提升)

需要我针对真实 API(StatsBomb/Football-Data) 接入,或用 Plotly/Tableau 风格做交互可视化版本吗?

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

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