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

wen python案例 7

本文目录导读:

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

  1. 方法1:基础百分比统计
  2. 方法2:按距离分段统计
  3. 方法3:可视化展示
  4. 方法4:完整统计分析类
  5. 方法5:分组对比分析
  6. 使用建议

方法1:基础百分比统计

import pandas as pd
import numpy as np
def pass_distribution_basic(passes):
    """
    基础长短传比例统计
    passes: 传球数据列表,每个元素为 {'distance': 距离(米), 'type': 传球类型}
    """
    # 将数据转换为DataFrame
    df = pd.DataFrame(passes)
    # 定义长短传标准(以25米为界)
    short_pass = df[df['distance'] < 25]
    long_pass = df[df['distance'] >= 25]
    # 计算比例
    total = len(df)
    short_ratio = len(short_pass) / total * 100
    long_ratio = len(long_pass) / total * 100
    return {
        'short_pass_count': len(short_pass),
        'long_pass_count': len(long_pass),
        'short_pass_ratio': round(short_ratio, 2),
        'long_pass_ratio': round(long_ratio, 2),
        'total_pass': total
    }
# 示例数据
passes = [
    {'distance': 15, 'type': 'ground'},
    {'distance': 30, 'type': 'air'},
    {'distance': 20, 'type': 'ground'},
    {'distance': 40, 'type': 'air'},
    {'distance': 10, 'type': 'ground'},
]
result = pass_distribution_basic(passes)
print(result)

方法2:按距离分段统计

def pass_distance_distribution(passes, bins=None):
    """
    按距离区间统计传球分布
    """
    df = pd.DataFrame(passes)
    if bins is None:
        bins = [0, 10, 20, 30, 40, 50, float('inf')]
        labels = ['0-10m', '10-20m', '20-30m', '30-40m', '40-50m', '50m+']
    # 创建距离区间
    df['distance_range'] = pd.cut(df['distance'], bins=bins, labels=labels, right=False)
    # 统计各区间数量
    distribution = df['distance_range'].value_counts().sort_index()
    # 计算比例
    total = len(df)
    ratio_distribution = (distribution / total * 100).round(2)
    return pd.DataFrame({
        'count': distribution,
        'percentage': ratio_distribution
    })
# 使用示例
result_df = pass_distance_distribution(passes)
print(result_df)

方法3:可视化展示

import matplotlib.pyplot as plt
import seaborn as sns
def pass_visualization(df):
    """
    传球分布可视化
    """
    fig, axes = plt.subplots(1, 2, figsize=(12, 5))
    # 长短期传球饼图
    short_count = len(df[df['distance'] < 25])
    long_count = len(df[df['distance'] >= 25])
    axes[0].pie([short_count, long_count], 
                labels=['短传', '长传'], 
                autopct='%1.1f%%',
                colors=['#66b3ff', '#ff9999'])
    axes[0].set_title('长短传比例分布')
    # 距离直方图
    df['distance'].hist(ax=axes[1], bins=20, color='skyblue', alpha=0.7)
    axes[1].set_title('传球距离分布')
    axes[1].set_xlabel('传球距离(米)')
    axes[1].set_ylabel('传球次数')
    plt.tight_layout()
    plt.show()
# 生成更多示例数据
np.random.seed(42)
pass_data = []
for _ in range(100):
    distance = np.random.normal(30, 10)
    distance = max(5, min(60, distance))  # 限制范围
    pass_data.append({'distance': distance, 'type': np.random.choice(['ground', 'air'])})
pass_visualization(pd.DataFrame(pass_data))

方法4:完整统计分析类

class PassAnalyzer:
    """
    传球分析器类
    """
    def __init__(self, passes_data):
        self.df = pd.DataFrame(passes_data)
        self.total = len(self.df)
    def short_long_ratio(self, threshold=25):
        """计算长短传比例"""
        short = self.df[self.df['distance'] < threshold]
        long = self.df[self.df['distance'] >= threshold]
        return {
            'short': {
                'count': len(short),
                'percentage': round(len(short) / self.total * 100, 2)
            },
            'long': {
                'count': len(long),
                'percentage': round(len(long) / self.total * 100, 2)
            }
        }
    def stats_summary(self):
        """统计摘要"""
        return {
            'total_passes': self.total,
            'mean_distance': round(self.df['distance'].mean(), 2),
            'median_distance': round(self.df['distance'].median(), 2),
            'max_distance': round(self.df['distance'].max(), 2),
            'min_distance': round(self.df['distance'].min(), 2)
        }
    def distribution_by_type(self):
        """按传球类型统计"""
        type_stats = self.df.groupby('type')['distance'].agg(['count', 'mean', 'std'])
        type_stats['percentage'] = (type_stats['count'] / self.total * 100).round(2)
        return type_stats
# 使用示例
analyzer = PassAnalyzer(passes)
print("长短传比例:", analyzer.short_long_ratio())
print("统计摘要:", analyzer.stats_summary())
print("按类型分布:")
print(analyzer.distribution_by_type())

方法5:分组对比分析

def compare_teams_pass_ratio(team1_data, team2_data):
    """
    对比两支队伍的长短传比例
    """
    team1_analyzer = PassAnalyzer(team1_data)
    team2_analyzer = PassAnalyzer(team2_data)
    comparison = pd.DataFrame({
        'Team1': team1_analyzer.short_long_ratio(),
        'Team2': team2_analyzer.short_long_ratio()
    })
    return comparison
# 示例
team1_passes = [{'distance': np.random.uniform(5, 50)} for _ in range(80)]
team2_passes = [{'distance': np.random.uniform(10, 60)} for _ in range(80)]
comparison = compare_teams_pass_ratio(team1_passes, team2_passes)
print(comparison)

使用建议

  1. 阈值选择:长短传的标准可以根据不同场景调整(排球20m,足球25-30m,篮球15m)
  2. 数据清洗:确保数据质量,去除异常值
  3. 结果解释:结合具体比赛场景解释数据
  4. 动态分析:可以按时间段或比赛阶段进行动态分析

这些方法可以根据您的具体需求选择使用,如果需要更多特定功能的实现,请告诉我具体需求。

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