python案例统计长短传比例如何分布?

wen python案例 4

Python 案例:统计长短传比例分布

下面通过几个不同场景的案例,演示如何统计"长传/短传"比例并分析分布。

python案例统计长短传比例如何分布?

案例1:基础足球传球数据统计

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 构造模拟传球数据
np.random.seed(42)
data = {
    'player': np.random.choice(['A', 'B', 'C', 'D'], 500),
    'distance': np.random.gamma(2, 8, 500),  # 传球距离(米)
}
df = pd.DataFrame(data)
# 定义长短传阈值(如15米)
THRESHOLD = 15
df['type'] = df['distance'].apply(lambda x: '长传' if x >= THRESHOLD else '短传')
# 全局比例
ratio = df['type'].value_counts(normalize=True)
print("=== 全局长短传比例 ===")
print(ratio.round(3))
# 每个球员的比例
by_player = df.groupby('player')['type'].value_counts(normalize=True).unstack(fill_value=0)
print("\n=== 各球员长短传比例 ===")
print(by_player.round(3))

案例2:距离分箱后的分布直方图

# 传球距离分布(直方图)
plt.figure(figsize=(10, 4))
plt.subplot(1, 2, 1)
df['distance'].hist(bins=30, edgecolor='black')
plt.axvline(THRESHOLD, color='red', linestyle='--', label=f'阈值 {THRESHOLD}m')'传球距离分布')
plt.xlabel('距离(米)')
plt.ylabel('次数')
plt.legend()
# 比例柱状图
plt.subplot(1, 2, 2)
ratio.plot(kind='bar', color=['steelblue', 'orange'])'长传/短传比例')
plt.ylabel('比例')
plt.xticks(rotation=0)
plt.tight_layout()
plt.show()

案例3:按距离区间(bins)统计分布

# 按距离区间分段统计
bins = [0, 5, 10, 15, 25, 40, 100]
labels = ['0-5m', '5-10m', '10-15m', '15-25m', '25-40m', '40m+']
df['bin'] = pd.cut(df['distance'], bins=bins, labels=labels)
bin_dist = df['bin'].value_counts().sort_index()
bin_pct = (bin_dist / len(df) * 100).round(1)
print("=== 距离区间分布 ===")
summary = pd.DataFrame({'次数': bin_dist, '占比%': bin_pct})
print(summary)
# 柱状图
bin_pct.plot(kind='bar', color='teal', figsize=(8, 4))'传球距离区间分布')
plt.ylabel('占比 (%)')
plt.xticks(rotation=0)
plt.tight_layout()
plt.show()

案例4:含时间维度的长短传趋势(比赛分阶段)

# 加入比赛分钟
df['minute'] = np.random.randint(1, 91, len(df))
# 按15分钟分段
df['period'] = pd.cut(df['minute'],
                      bins=[0, 15, 30, 45, 60, 75, 90],
                      labels=['0-15', '15-30', '30-45', '45-60', '60-75', '75-90'])
period_ratio = (df.groupby(['period', 'type'], observed=True)
                  .size()
                  .unstack(fill_value=0))
period_ratio['长传比例'] = period_ratio['长传'] / period_ratio.sum(axis=1)
print("=== 各阶段传球比例 ===")
print(period_ratio.round(3))
# 折线图
period_ratio['长传比例'].plot(marker='o', figsize=(8, 4))'各时段长传比例变化')
plt.ylabel('长传占比')
plt.grid(alpha=0.3)
plt.tight_layout()
plt.show()

案例5:完整流程封装函数

def analyze_pass_distribution(df, dist_col='distance', threshold=15, group_col=None):
    """
    统计长短传比例分布
    返回:全局比例、分箱分布、分组比例(可选)
    """
    df = df.copy()
    df['type'] = np.where(df[dist_col] >= threshold, '长传', '短传')
    overall = df['type'].value_counts(normalize=True)
    bins = [0, 5, 10, threshold, 25, 40, np.inf]
    labels = [f'0-5m', f'5-10m', f'10-{threshold}m',
              f'{threshold}-25m', '25-40m', '40m+']
    df['bin'] = pd.cut(df[dist_col], bins=bins, labels=labels)
    bin_dist = df['bin'].value_counts(normalize=True).sort_index()
    grouped = None
    if group_col:
        grouped = (df.groupby(group_col)['type']
                     .value_counts(normalize=True)
                     .unstack(fill_value=0))
    return {
        'overall': overall,
        'by_bin': bin_dist,
        'by_group': grouped
    }
result = analyze_pass_distribution(df, group_col='player')
print(result['overall'].round(3))
print(result['by_bin'].round(3))
print(result['by_group'].round(3))

关键要点

要点 说明
阈值定义 长传阈值常见为 15/20/25 米(依联赛或战术标准)
比例计算 value_counts(normalize=True) 快速求占比
分布分析 用 pd.cut 分箱后统计,比单一阈值更有洞察力
多维对比 按球员/时段/场次分组更能反映战术差异
可视化 直方图看原始分布,柱状图看区间占比,折线图看趋势

需要我针对真实比赛数据(如 StatsBomb / Opta)、篮球长短传或其他领域(如网络传输包大小)的变体案例继续展开吗?

上一篇python案例统计红黄牌数量哪队更多?

下一篇当前分类已是最新一篇

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