Python案例:统计足球比赛中"马赛回旋"使用频率
"马赛回旋"(Roulette / Maradona Turn / Zidane Turn)是一种经典的过人动作,下面我用 Python 演示如何从比赛事件数据中统计它的使用频率。

数据准备
通常在足球数据中(如 StatsBomb、OPTA),过人动作会记录在 dribble 事件中,并带有 technique 或 move 标签,我们模拟一份数据:
import pandas as pd
import matplotlib.pyplot as plt
# 模拟一场比赛的事件数据
data = {
"minute": [5, 8, 15, 22, 30, 38, 45, 52, 60, 67, 75, 82, 88],
"player": ["梅西","姆巴佩","梅西","维拉蒂","内马尔","梅西",
"姆巴佩","内马尔","梅西","维拉蒂","梅西","内马尔","姆巴佩"],
"dribble_type": ["马赛回旋","普通过人","马赛回旋","牛尾巴","马赛回旋",
"普通过人","马赛回旋","普通过人","马赛回旋","牛尾巴",
"马赛回旋","普通过人","马赛回旋"],
"success": [True, True, False, True, True, True, True, False, True, False, True, True, True]
}
df = pd.DataFrame(data)
print(df.head())
统计整体使用频率
total = len(df)
marseille = df[df["dribble_type"] == "马赛回旋"]
count = len(marseille)
rate = count / total * 100
print(f"总过人次数: {total}")
print(f"马赛回旋次数: {count}")
print(f"马赛回旋使用频率: {rate:.2f}%")
print(f"成功率: {marseille['success'].mean()*100:.1f}%")
示例输出:
总过人次数: 13
马赛回旋次数: 7
马赛回旋使用频率: 53.85%
成功率: 85.7%
按球员统计
# 各球员马赛回旋次数
by_player = (df[df["dribble_type"] == "马赛回旋"]
.groupby("player")
.size()
.sort_values(ascending=False))
print("\n各球员马赛回旋次数:")
print(by_player)
可视化
plt.rcParams["font.sans-serif"] = ["SimHei"] # 中文显示
plt.rcParams["axes.unicode_minus"] = False
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
# 图1:打法类型分布
df["dribble_type"].value_counts().plot(kind="bar", ax=axes[0], color="steelblue")
axes[0].set_title("各种过人动作使用次数")
axes[0].set_ylabel("次数")
# 图2:球员马赛回旋次数
by_player.plot(kind="barh", ax=axes[1], color="orange")
axes[1].set_title("各球员马赛回旋次数")
axes[1].set_xlabel("次数")
plt.tight_layout()
plt.savefig("marseille_turn.png", dpi=120)
plt.show()
进阶:时间轴 / 分段统计
# 按 15 分钟区间统计
bins = [0, 15, 30, 45, 60, 75, 90]
df["interval"] = pd.cut(df["minute"], bins=bins, right=False)
marseille_df = df[df["dribble_type"] == "马赛回旋"]
timeline = marseille_df.groupby("interval", observed=True).size()
print("\n马赛回旋时间分布:")
print(timeline)
timeline.plot(kind="bar", color="green", title="马赛回旋按时间段分布")
plt.xlabel("时间段(分钟)")
plt.ylabel("次数")
plt.tight_layout()
plt.show()
对接真实数据的思路
如果接入 StatsBomb Open Data(免费):
from statsbombpy import sb
events = sb.events(match_id=3788741) # 某场比赛ID
dribbles = events[events["type"] == "Dribble"].copy()
# 查看 dribble 的细分字段
print(dribbles["dribble"].apply(pd.Series).columns)
# 通常含 'overrun', 'nutmeg', 'roulette'(马赛回旋)等布尔特征
roulette = dribbles[dribbles["dribble"].apply(lambda x: x.get("roulette", False))]
print(f"马赛回旋使用次数: {len(roulette)}")
StatsBomb 的 dribble 子字段里
roulette就是马赛回旋的布尔标记,非常方便统计。
| 步骤 | 说明 |
|---|---|
| 数据来源 | 事件 API(StatsBomb/OPTA)或手动记录 |
| 识别方式 | 按 dribble_type 或 StatsBomb 的 roulette 字段 |
| 频率指标 | 占总过人比例、每 90 分钟次数、分时段分布 |
| 可视化 | 柱状图、时间轴、按球员排行 |
如果你有具体的比赛数据(CSV / JSON / API),贴出来我可以帮你写针对性的统计代码。