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

wen python案例 2

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

"马赛回旋"(Marseille Turn / La Roulette)是齐达内的标志性过人动作,下面给你一个可运行的完整方案,从数据获取到统计可视化。

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


整体思路

数据源(比赛事件/视频/文本) → 动作识别/标注 → 频次统计 → 可视化分析

根据你的数据条件,有三种实现路径:

数据条件 方法 难度
有结构化事件数据(如StatsBomb) 直接统计事件类型
只有比赛视频 CV动作识别
只有文字解说/报道 NLP关键词抽取

方案A:基于结构化事件数据(推荐入门)

数据来源

  • StatsBomb Open Data(免费,含梅西、世界杯等)
  • Wyscout、Opta 付费数据

代码示例

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
# 假设已有事件数据 events.csv,字段:player, match_id, event_type, minute
# StatsBomb 中类似动作通常标注为 "Turn" 或自定义标签 "Marseille Turn"
df = pd.read_csv("events.csv")
# 筛选马赛回旋事件
mt = df[df["event_type"] == "Marseille Turn"]
# 1) 按球员统计使用频率
freq_by_player = (
    mt.groupby("player")
      .size()
      .sort_values(ascending=False)
      .head(10)
)
print(freq_by_player)
# 2) 按90分钟归一化(考虑出场时间)
minutes = df.groupby("player")["minute"].max()
freq_per90 = (mt.groupby("player").size() / minutes * 90).dropna()
# 3) 可视化
plt.rcParams["font.sans-serif"] = ["SimHei"]      # 中文显示
plt.rcParams["axes.unicode_minus"] = False
fig, ax = plt.subplots(1, 2, figsize=(14, 5))
freq_by_player.plot(kind="barh", ax=ax[0], color="steelblue")
ax[0].set_title("马赛回旋使用次数 TOP10")
ax[0].set_xlabel("次数")
freq_per90.sort_values(ascending=False).head(10).plot(
    kind="barh", ax=ax[1], color="coral")
ax[1].set_title("每90分钟马赛回旋频率 TOP10")
ax[1].set_xlabel("次/90min")
plt.tight_layout()
plt.savefig("marseille_turn.png", dpi=150)

方案B:基于比赛视频(计算机视觉)

技术栈

  • 姿态估计:MediaPipe / YOLOv8-Pose
  • 动作分类:ST-GCN / SlowFast / Transformer
  • 跟踪:ByteTrack

核心流程

import cv2
import mediapipe as mp
import numpy as np
mp_pose = mp.solutions.pose
pose = mp_pose.Pose()
def extract_keypoints(video_path):
    """提取每帧人体关键点"""
    cap = cv2.VideoCapture(video_path)
    seq = []
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        res = pose.process(cv2.cvtColor(frame, cv2.COLOR_BGR2RGB))
        if res.pose_landmarks:
            kp = np.array([[l.x, l.y, l.z] for l in res.pose_landmarks.landmark])
            seq.append(kp.flatten())
    return np.array(seq)   # shape: (T, 99)
# 判定马赛回旋的启发式规则(简化版):
# 1. 身体绕垂直轴旋转 > 180°
# 2. 单脚支撑 (另一只脚抬起)
# 3. 球在脚下控制
def is_marseille_turn(seq, fps=25, window=1.0):
    """基于髋部横向位移+肩部朝向变化做粗略判断"""
    n = int(fps * window)
    for i in range(len(seq) - n):
        win = seq[i:i+n].reshape(n, 33, 3)
        # 肩部向量角度变化
        left_shoulder, right_shoulder = win[:, 11, :2], win[:, 12, :2]
        vec = right_shoulder - left_shoulder
        angles = np.arctan2(vec[:, 1], vec[:, 0])
        delta = np.abs(np.unwrap(angles)[-1] - np.unwrap(angles)[0])
        if np.degrees(delta) > np.pi:      # 旋转超180°
            return True
    return False
# 批量统计
video_count = 0
for path in ["match1.mp4", "match2.mp4"]:
    seq = extract_keypoints(path)
    if is_marseille_turn(seq):
        video_count += 1
print(f"视频中出现马赛回旋次数: {video_count}")

⚠️ 实际生产需训练专用分类模型(收集带标签的切片)才能达到可用精度,启发式规则仅作 demo。


方案C:基于文字报道/解说(NLP)

import re, jieba
from collections import Counter
keywords = ["马赛回旋", "拉球转身", "马赛转身", "roulette", "marseille turn"]
def count_marseille(texts):
    """统计文本库中马赛回旋出现次数 + 关联球员"""
    cnt = Counter()
    for t in texts:
        for kw in keywords:
            for m in re.finditer(kw, t):
                # 提取前后10字作为上下文
                start = max(0, m.start()-10)
                ctx = t[start:m.end()+10]
                cnt[kw] += 1
                print(f"[{kw}] ...{ctx}...")
    return cnt
# 示例
articles = [
    "齐达内在中场完成一次经典马赛回旋摆脱防守",
    "内马尔禁区前沿马赛回旋过两人,引爆全场"
]
print(count_marseille(articles))

结果呈现(推荐分析维度)

一个完整的分析报告通常包含:

  1. 球员维度:TOP10使用次数 / 每90min频率
  2. 场景维度:前场/中场/后场、比分领先/落后时频率
  3. 时间维度:赛季趋势、比赛第几十分钟最常用
  4. 成功率:马赛回旋后是否成功推进/传球(需事件链)
  5. 对比分析:齐达内 vs 内马尔 vs 现代球员

示例可视化:

# 热力图:不同球员×赛季 的使用频率
pivot = mt.pivot_table(index="player", columns="season",
                       values="event_id", aggfunc="count", fill_value=0)
sns.heatmap(pivot, cmap="YlOrRd", annot=True)"马赛回旋使用频率热力图")
plt.show()

现实难点与建议

难点 建议
"马赛回旋"非标准化事件 建立自定义标注规范(旋转≥180°+单脚支撑+控球)
视频识别精度低 用标注数据微调 ST-GCN,配合球员跟踪
数据获取成本高 先用 StatsBomb 公开数据练手
样本少 交叉验证 + 置信区间,避免过度解读

如果你告诉我手头有什么数据(CSV事件表?比赛视频?新闻文本?),我可以帮你把上面某一方案改成直接可跑的完整脚本。

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