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

wen python案例 1

本文目录导读:

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

  1. 基础版本:简单统计分析
  2. 进阶版本:更复杂的分析
  3. 可视化增强版本

我来为您提供一个统计长短传比例分布的Python案例。

基础版本:简单统计分析

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from collections import Counter
# 示例数据:模拟传球数据
def generate_sample_data():
    """生成模拟传球数据"""
    np.random.seed(42)
    # 生成1000个传球数据
    passes = []
    for i in range(1000):
        # 随机生成传球距离(5-50米)
        distance = np.random.uniform(5, 50)
        # 根据距离分类
        if distance <= 15:
            pass_type = '短传'
        elif distance <= 25:
            pass_type = '中传'
        else:
            pass_type = '长传'
        passes.append({
            'player_id': np.random.randint(1, 20),
            'distance': distance,
            'pass_type': pass_type,
            'success': np.random.choice([True, False], p=[0.85, 0.15])
        })
    return pd.DataFrame(passes)
# 统计分析函数
def analyze_pass_distribution(df):
    """分析传球类型分布"""
    print("="*60)
    print("传球类型分布统计")
    print("="*60)
    # 总体分布
    type_counts = df['pass_type'].value_counts()
    type_percentages = df['pass_type'].value_counts(normalize=True) * 100
    print("\n📊 传球类型总体分布:")
    for pass_type in ['短传', '中传', '长传']:
        if pass_type in type_counts.index:
            count = type_counts[pass_type]
            percentage = type_percentages[pass_type]
            print(f"  {pass_type}: {count}次 ({percentage:.1f}%)")
    # 按球员统计
    print("\n👥 按球员统计:")
    player_stats = df.groupby('player_id').agg({
        'pass_type': ['count', lambda x: (x == '短传').sum(), 
                     lambda x: (x == '长传').sum()]
    }).round(2)
    # 计算比例
    for player in df['player_id'].unique():
        player_data = df[df['player_id'] == player]
        total = len(player_data)
        short_passes = len(player_data[player_data['pass_type'] == '短传'])
        long_passes = len(player_data[player_data['pass_type'] == '长传'])
        if total > 0:
            short_ratio = short_passes / total * 100
            long_ratio = long_passes / total * 100
            print(f"  球员{player}: 短传{short_ratio:.1f}% / 长传{long_ratio:.1f}%")
    return type_counts, type_percentages
# 创建图表
def plot_distribution(df):
    """创建图表展示分布"""
    fig, axes = plt.subplots(2, 2, figsize=(15, 10))
    # 1. 传球类型饼图
    ax1 = axes[0, 0]
    type_counts = df['pass_type'].value_counts()
    type_counts.plot.pie(
        ax=ax1,
        autopct='%1.1f%%',
        colors=['#4CAF50', '#FFC107', '#FF5722']
    )
    ax1.set_title('传球类型分布')
    # 2. 传球距离分布直方图
    ax2 = axes[0, 1]
    colors = ['green' if t == '短传' else 'orange' if t == '中传' else 'red' 
              for t in df['pass_type']]
    ax2.hist(df['distance'], bins=30, color='steelblue', alpha=0.6)
    ax2.axvline(x=15, color='green', linestyle='--', alpha=0.8, label='短传阈值')
    ax2.axvline(x=25, color='red', linestyle='--', alpha=0.8, label='长传阈值')
    ax2.set_xlabel('传球距离(米)')
    ax2.set_ylabel('频次')
    ax2.set_title('传球距离分布')
    ax2.legend()
    # 3. 球员传球风格散点图
    ax3 = axes[1, 0]
    player_short_ratio = []
    player_long_ratio = []
    for player in df['player_id'].unique():
        player_data = df[df['player_id'] == player]
        if len(player_data) > 0:
            short_ratio = len(player_data[player_data['pass_type'] == '短传']) / len(player_data) * 100
            long_ratio = len(player_data[player_data['pass_type'] == '长传']) / len(player_data) * 100
            player_short_ratio.append(short_ratio)
            player_long_ratio.append(long_ratio)
    ax3.scatter(player_short_ratio, player_long_ratio, alpha=0.6)
    ax3.set_xlabel('短传比例 (%)')
    ax3.set_ylabel('长传比例 (%)')
    ax3.set_title('球员传球风格')
    # 4. 短传成功率对比
    ax4 = axes[1, 1]
    success_rates = df.groupby('pass_type')['success'].mean() * 100
    success_rates.plot(kind='bar', ax=ax4, color=['#4CAF50', '#FFC107', '#FF5722'])
    ax4.set_title('各类型传球成功率')
    ax4.set_xlabel('传球类型')
    ax4.set_ylabel('成功率 (%)')
    ax4.set_ylim(80, 100)
    plt.tight_layout()
    plt.show()
# 主执行
if __name__ == "__main__":
    # 生成数据
    df = generate_sample_data()
    # 统计分析
    analyze_pass_distribution(df)
    # 绘制图表
    plot_distribution(df)
    # 输出详细统计结果
    print("\n📊 详细统计结果:")
    print(df.groupby('pass_type').agg({
        'distance': ['mean', 'std', 'min', 'max'],
        'success': 'mean'
    }).round(2))

进阶版本:更复杂的分析

import pandas as pd
import numpy as np
from scipy import stats
class PassAnalyzer:
    """传球数据高级分析器"""
    def __init__(self, data):
        self.df = data
        self.calculate_metrics()
    def calculate_metrics(self):
        """计算高级指标"""
        self.df['pass_precision'] = np.random.uniform(70, 95, len(self.df))  # 传球精度
        # 计算传球稳定性
        self.df['pass_risk'] = self.df['distance'].apply(
            lambda x: 0.1 if x < 10 else 0.3 if x < 20 else 0.5
        )
    def statistical_tests(self):
        """统计检验"""
        print("\n🧪 统计检验结果:")
        # 短传和长传距离的显著性检验
        short_passes = self.df[self.df['pass_type'] == '短传']['pass_precision']
        long_passes = self.df[self.df['pass_type'] == '长传']['pass_precision']
        t_stat, p_value = stats.ttest_ind(short_passes, long_passes)
        print(f"短传vs长传精度t检验: t={t_stat:.3f}, p={p_value:.3f}")
        # 卡方检验
        contingency_table = pd.crosstab(self.df['pass_type'], self.df['success'])
        chi2, chi2_p, dof, expected = stats.chi2_contingency(contingency_table)
        print(f"卡方检验: χ²={chi2:.3f}, p={chi2_p:.3f}")
    def compare_players(self):
        """比较不同球员的传球风格"""
        print("\n🏃 球员传球风格比较:")
        player_summary = []
        for player in self.df['player_id'].unique():
            player_data = self.df[self.df['player_id'] == player]
            if len(player_data) >= 10:  # 确保样本量
                avg_distance = player_data['distance'].mean()
                success_rate = player_data['success'].mean() * 100
                short_count = len(player_data[player_data['pass_type'] == '短传'])
                long_count = len(player_data[player_data['pass_type'] == '长传'])
                player_summary.append({
                    'player_id': player,
                    'avg_distance': avg_distance,
                    'success_rate': success_rate,
                    'short_passes': short_count,
                    'long_passes': long_count,
                    'short_ratio': short_count / len(player_data) * 100,
                    'long_ratio': long_count / len(player_data) * 100
                })
        summary_df = pd.DataFrame(player_summary)
        print(summary_df.to_string(index=False))
        return summary_df
    def generate_report(self):
        """生成综合报告"""
        print("\n" + "="*60)
        print("🗒️ 传球数据分析报告")
        print("="*60)
        # 总体统计
        print(f"\n📈 总体统计指标:")
        print(f"  - 总传球数: {len(self.df)}")
        print(f"  - 平均传球距离: {self.df['distance'].mean():.2f}米")
        print(f"  - 传球成功率: {self.df['success'].mean()*100:.1f}%")
        # 类型分布
        print(f"\n🎯 类型分布:")
        for pass_type in ['短传', '中传', '长传']:
            count = len(self.df[self.df['pass_type'] == pass_type])
            percentage = count / len(self.df) * 100
            print(f"  - {pass_type}: {percentage:.1f}% ({count}次)")
        # 推荐建议
        print(f"\n💡 分析建议:")
        short_ratio = len(self.df[self.df['pass_type'] == '短传']) / len(self.df) * 100
        if short_ratio > 60:
            print("  - 球队偏向短传控制型打法")
        elif short_ratio < 40:
            print("  - 球队偏向长传进攻型打法")
        else:
            print("  - 球队打法较为均衡")
# 使用示例
if __name__ == "__main__":
    # 生成测试数据
    df = generate_sample_data()
    # 创建分析对象
    analyzer = PassAnalyzer(df)
    # 执行分析
    analyzer.statistical_tests()
    analyzer.compare_players()
    analyzer.generate_report()

可视化增强版本

import seaborn as sns
from matplotlib.colors import LinearSegmentedColormap
# 高级可视化
def advanced_visualization(df):
    """高级可视化分析"""
    fig, axes = plt.subplots(3, 2, figsize=(18, 14))
    # 1. 热力图:球员×传球类型
    ax1 = axes[0, 0]
    pivot_table = df.pivot_table(
        index='player_id', 
        columns='pass_type', 
        values='distance', 
        aggfunc='count'
    ).fillna(0)
    sns.heatmap(pivot_table, ax=ax1, annot=True, cmap='YlOrRd', fmt='g')
    ax1.set_title('球员传球类型热力图')
    # 2. 箱线图:传球距离分布
    ax2 = axes[0, 1]
    sns.boxplot(data=df, x='pass_type', y='distance', ax=ax2, 
                palette=['#4CAF50', '#FFC107', '#FF5722'])
    ax2.set_title('各类型传球距离分布')
    # 3. 时间序列(如果有多场比赛数据)
    ax3 = axes[1, 0]
    if 'match_id' not in df.columns:
        df['match_id'] = 1  # 默认单场
    match_stats = df.groupby(['match_id', 'pass_type']).size().unstack().fillna(0)
    match_stats.plot(kind='line', ax=ax3, marker='o')
    ax3.set_title('比赛传球类型趋势')
    # 4. 雷达图:球员综合能力
    ax4 = axes[1, 1]
    # 选择一个典型球员示例
    player = df.iloc[0]['player_id']
    player_data = df[df['player_id'] == player]
    categories = ['短传', '中传', '长传', '成功率', '平均距离']
    values = [
        len(player_data[player_data['pass_type'] == '短传']) / len(player_data) * 20,
        len(player_data[player_data['pass_type'] == '中传']) / len(player_data) * 20,
        len(player_data[player_data['pass_type'] == '长传']) / len(player_data) * 20,
        player_data['success'].mean() * 20,
        player_data['distance'].mean() / 5
    ]
    angles = np.linspace(0, 2 * np.pi, len(categories), endpoint=False).tolist()
    values += values[:1]
    angles += angles[:1]
    ax4 = plt.subplot(3, 2, 4, polar=True)
    ax4.plot(angles, values)
    ax4.fill(angles, values, alpha=0.3)
    ax4.set_xticks(angles[:-1])
    ax4.set_xticklabels(categories)
    ax4.set_title(f'球员{player}能力雷达图')
    # 5. 密度图:传球距离概率密度
    ax5 = axes[2, 0]
    for pass_type in ['短传', '中传', '长传']:
        subset = df[df['pass_type'] == pass_type]
        sns.kdeplot(subset['distance'], ax=ax5, label=pass_type, shade=True)
    ax5.set_title('传球距离概率密度分布')
    # 6. 相关性矩阵
    ax6 = axes[2, 1]
    numeric_df = df[['distance', 'pass_precision', 'pass_risk', 'success']]
    corr_matrix = numeric_df.corr()
    sns.heatmap(corr_matrix, ax=ax6, annot=True, cmap='coolwarm', fmt='.2f')
    ax6.set_title('传球指标相关性矩阵')
    plt.tight_layout()
    plt.show()

这个案例包含了:

  1. 基础统计分析:传球类型分布、比例计算
  2. 高级分析:统计检验、球员风格比较
  3. 多样化可视化:饼图、直方图、热力图、雷达图等

您可以根据实际数据格式调整字段名和阈值标准,需要更具体的功能吗?

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