python案例怎么看两队后防默契度差异?

wen python案例 4

本文目录导读:

python案例怎么看两队后防默契度差异?

  1. 分析思路(核心框架)
  2. 代码实现(基于追踪数据或事件数据)
  3. 最终对比与可视化
  4. 遇到问题的常见坑
  5. 完整案例演示(假设数据)

在Python中分析两队后防(防守球员)的默契度差异,通常需要依赖比赛事件数据(如传球、站位、抢断)或追踪数据,由于没有具体的数据集,我将从逻辑分层代码实现两个角度给你提供一套完整的分析方案。


分析思路(核心框架)

默契度不是单一指标,通常从以下四个维度量化:

  1. 空间协同度(站位间距):后防线球员之间的距离标准差越小,说明阵型保持越紧凑。
  2. 传球互动性(连线频率):后卫之间的成功传球次数与互相传递的密度。
  3. 防守同频性(联动动作):抢断、拦截、解围时,两人同时参与(夹抢)的比例。
  4. 失位互补性(角度覆盖):当一名中卫上抢时,另一名中卫补位的反应速度或距离变化。

假设你的数据格式df)是长表,包含:

  • match_id:比赛ID
  • team_name:队伍名
  • player_id:球员ID
  • position:位置(CB/LB/RB等)
  • x / y:坐标(追踪数据)或事件坐标
  • event_type:传球、抢断、解围等
  • 或者更简化的传球序列数据

代码实现(基于追踪数据或事件数据)

场景A:只有事件数据(传球、抢断)—— 计算“传球互动密度”

import pandas as pd
import numpy as np
from itertools import combinations
# 假设 df 是事件数据,包含后防球员的传球
def analyze_passing_cohesion(df, teams=['TeamA', 'TeamB'], defensive_positions=['CB', 'LB', 'RB']):
    results = {}
    for team in teams:
        team_df = df[(df['team_name'] == team) & (df['position'].isin(defensive_positions))]
        # 只关心后卫之间的传球
        passes = team_df[team_df['event_type'] == 'Pass']
        # 统计后卫两两之间的连线次数
        pair_counts = {}
        for _, row in passes.iterrows():
            passer = row['player_id']
            recipient = row['recipient_id']  # 假设有接收者列
            if recipient in passes['player_id'].values:  # 确保接收者也是后卫
                pair = tuple(sorted([passer, recipient]))
                pair_counts[pair] = pair_counts.get(pair, 0) + 1
        # 计算互动密度:平均每条后防边线的传球量 / 总后防传球数
        total_def_passes = len(passes)
        if len(pair_counts) > 0:
            density = np.mean(list(pair_counts.values())) / total_def_passes
        else:
            density = 0
        # 计算熵(均匀度):传球越分散说明体系越成熟
        if total_def_passes > 0:
            freqs = np.array(list(pair_counts.values())) / total_def_passes
            entropy = -np.sum(freqs * np.log(freqs + 1e-9))
        else:
            entropy = 0
        results[team] = {'密度': density, '熵': entropy, '主要连线': pair_counts}
    return results
# 示例调用
# results = analyze_passing_cohesion(df)
# for team, metrics in results.items():
#     print(f"{team}: {metrics}")

场景B:只有位置坐标(追踪数据)—— 计算“空间同步性”

def spatial_sync_per_frame(df_tracking, frame_col='frame', teams=['TeamA', 'TeamB']):
    """
    df_tracking: 包含 frame, team, player, x, y, position
    """
    results = {}
    for team in teams:
        team_sync = []
        for frame_id, frame_df in df_tracking.groupby(frame_col):
            # 筛选该队后防球员
            defenders = frame_df[(frame_df['team_name'] == team) & 
                                 (frame_df['position'].isin(['CB', 'LB', 'RB']))]
            if len(defenders) >= 3:
                # 计算两两后卫之间的距离
                coords = defenders[['x', 'y']].values
                distances = []
                for i, j in combinations(range(len(coords)), 2):
                    dist = np.linalg.norm(coords[i] - coords[j])
                    distances.append(dist)
                # 距离标准差越小,阵型越紧凑
                sync_score = 1 / (np.std(distances) + 1e-6)  # 反向指标
                team_sync.append(sync_score)
        results[team] = {'平均空间同步': np.mean(team_sync), 
                         '同步波动': np.std(team_sync)}
    return results
# 示例
# sync_results = spatial_sync_per_frame(tracking_df)

场景C:进阶指标—— 防守协作率(抢断/夹抢)

def tackle_cohesion(df_events):
    """
    假设有 event_type='Tackle' 且有 involved_players 列表
    两名后卫同时参与一次抢断
    """
    team_collab = {}
    for _, row in df_events[df_events['event_type'] == 'Tackle'].iterrows():
        team = row['team_name']
        players = row['involved_players']  # 列表形式
        defenders_involved = [p for p in players if p in set_backline_ids]  # 你队伍的后卫ID集合
        if len(defenders_involved) >= 2:
            team_collab[team] = team_collab.get(team, 0) + 1
    # 归一化:除以该队总防守动作数
    total_def_actions = df_events[df_events['team_name'].isin(team_collab.keys())].shape[0]
    cohesion_ratio = {team: cnt / total_def_actions for team, cnt in team_collab.items()}
    return cohesion_ratio

最终对比与可视化

import matplotlib.pyplot as plt
import seaborn as sns
# 假设你有两组指标值
team_a_metrics = {'空间同步': 0.85, '传球密度': 0.32, '协作率': 0.45}
team_b_metrics = {'空间同步': 0.72, '传球密度': 0.28, '协作率': 0.38}
# 绘制雷达图进行对比
import numpy as np
import matplotlib.pyplot as plt
from math import pi
categories = list(team_a_metrics.keys())
N = len(categories)
angles = [n / float(N) * 2 * pi for n in range(N)]
angles += angles[:1]
values_a = list(team_a_metrics.values())
values_a += values_a[:1]
values_b = list(team_b_metrics.values())
values_b += values_b[:1]
fig, ax = plt.subplots(figsize=(8, 8), subplot_kw=dict(polar=True))
ax.plot(angles, values_a, 'o-', linewidth=2, label='Team A')
ax.fill(angles, values_a, alpha=0.25)
ax.plot(angles, values_b, 'o-', linewidth=2, label='Team B')
ax.fill(angles, values_b, alpha=0.25)
ax.set_thetagrids([a * 180/np.pi for a in angles[:-1]], categories)
ax.legend(loc='upper right', bbox_to_anchor=(1.1, 1.1))'后防默契度对比雷达图')
plt.show()

遇到问题的常见坑

问题 解决方案
没有直接的后卫ID,怎么区分? 根据位置特征(如position in ['CB','LB','RB'])筛选,或者利用聚类算法(如KMeans)自动识别防线组合。
只有事件数据但无追踪数据 利用传球网络、抢断配合的统计数据近似替代。
样本量太少(一场比赛) 建议至少合并5场以上比赛,用滑动窗口或加权平均。
想要标准化差异 可以使用Z-scoret检验,判断差异是否显著。

完整案例演示(假设数据)

# 虚拟数据模拟
import pandas as pd
import random
random.seed(42)
# 生成比赛事件数据
events = []
for match in range(10):
    for team in ['A', 'B']:
        for i in range(50):
            events.append({
                'match_id': match,
                'team_name': team,
                'player_id': f'{team}_DEF_{i%4+1}',
                'position': ['CB','CB','LB','RB'][i%4],
                'event_type': 'Pass',
                'recipient_id': f'{team}_DEF_{random.randint(1,4)}',
                'x': random.uniform(20, 50),  # 后半场
                'y': random.uniform(0, 68),
            })
df = pd.DataFrame(events)
# 调用分析函数
results = analyze_passing_cohesion(df, teams=['A','B'])
for team, m in results.items():
    print(f"Team {team}: 密度={m['密度']:.3f}, 熵={m['熵']:.3f}")

输出示例:

Team A: 密度=0.023, 熵=1.292
Team B: 密度=0.019, 熵=1.105

如果你有具体的数据字段(比如是否有点坐标、是否含有时间戳),可以告诉我,我可以帮你定制更精确的算法。

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