python案例统计假动作晃过防守几次?

wen python案例 5

本文目录导读:

python案例统计假动作晃过防守几次?

  1. 主要功能:
  2. 使用方式:
  3. 输出示例:

我来创建一个统计假动作晃过防守次数的Python案例,这个案例将包含数据定义、统计逻辑和可视化展示。

import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime
class DribblingAnalytics:
    """篮球/足球假动作晃过防守统计系统"""
    def __init__(self, player_name):
        self.player_name = player_name
        self.moves = []  # 存储所有动作记录
        self.stats = {}
    def add_move(self, date, opponent, move_type, successful, defender_name="", 
                 period=1, minute=0, notes=""):
        """
        添加一次假动作记录
        参数:
            date: 日期
            opponent: 对手
            move_type: 假动作类型
            successful: 是否成功晃过 (True/False)
            defender_name: 防守球员
            period: 节数/半场
            minute: 比赛时间
            notes: 备注
        """
        move = {
            '日期': date,
            '对手': opponent,
            '假动作类型': move_type,
            '成功晃过': successful,
            '防守球员': defender_name,
            '节数': period,
            '时间': minute,
            '备注': notes
        }
        self.moves.append(move)
        print(f"✓ 已记录: {date} vs {opponent} - {move_type} {'成功' if successful else '失败'}")
    def get_total_moves(self):
        """获取总动作次数"""
        return len(self.moves)
    def get_successful_moves(self):
        """获取成功晃过次数"""
        return sum(1 for move in self.moves if move['成功晃过'])
    def get_failed_moves(self):
        """获取失败次数"""
        return sum(1 for move in self.moves if not move['成功晃过'])
    def get_success_rate(self):
        """计算成功率"""
        total = self.get_total_moves()
        if total == 0:
            return 0
        return (self.get_successful_moves() / total) * 100
    def stats_by_move_type(self):
        """按假动作类型统计"""
        stats = {}
        for move in self.moves:
            move_type = move['假动作类型']
            if move_type not in stats:
                stats[move_type] = {'总次数': 0, '成功次数': 0, '失败次数': 0}
            stats[move_type]['总次数'] += 1
            if move['成功晃过']:
                stats[move_type]['成功次数'] += 1
            else:
                stats[move_type]['失败次数'] += 1
        # 计算成功率
        for move_type in stats:
            total = stats[move_type]['总次数']
            successful = stats[move_type]['成功次数']
            stats[move_type]['成功率'] = (successful / total * 100) if total > 0 else 0
        return stats
    def stats_by_opponent(self):
        """按对手统计"""
        stats = {}
        for move in self.moves:
            opponent = move['对手']
            if opponent not in stats:
                stats[opponent] = {'总次数': 0, '成功次数': 0}
            stats[opponent]['总次数'] += 1
            if move['成功晃过']:
                stats[opponent]['成功次数'] += 1
        return stats
    def get_most_difficult_defender(self):
        """找出最难突破的防守球员"""
        defender_stats = {}
        for move in self.moves:
            defender = move['防守球员']
            if not defender:
                continue
            if defender not in defender_stats:
                defender_stats[defender] = {'面对次数': 0, '成功次数': 0}
            defender_stats[defender]['面对次数'] += 1
            if move['成功晃过']:
                defender_stats[defender]['成功次数'] += 1
        # 找出最难突破的
        if not defender_stats:
            return None
        hardest_defender = min(defender_stats.items(), 
                              key=lambda x: x[1]['成功次数'] / x[1]['面对次数'] if x[1]['面对次数'] > 0 else 0)
        return hardest_defender
    def generate_report(self):
        """生成统计报告"""
        print("\n" + "=" * 50)
        print(f"📊 {self.player_name} 假动作统计分析报告")
        print("=" * 50)
        # 基本统计
        total = self.get_total_moves()
        success = self.get_successful_moves()
        failed = self.get_failed_moves()
        rate = self.get_success_rate()
        print(f"\n📈 基本统计:")
        print(f"  总假动作次数: {total}")
        print(f"  成功晃过: {success} 次")
        print(f"  未成功: {failed} 次")
        print(f"  成功率: {rate:.1f}%")
        # 按类型统计
        print("\n🎯 按假动作类型:")
        type_stats = self.stats_by_move_type()
        for move_type, stats in type_stats.items():
            print(f"  {move_type}:")
            print(f"    总次数: {stats['总次数']}")
            print(f"    成功: {stats['成功次数']}")
            print(f"    成功率: {stats['成功率']:.1f}%")
        # 按对手统计
        print("\n🏆 按对手统计:")
        opp_stats = self.stats_by_opponent()
        for opp, stats in opp_stats.items():
            print(f"  vs {opp}: 总{stats['总次数']}次, 成功{stats['成功次数']}次")
        # 最难防守球员
        hardest = self.get_most_difficult_defender()
        if hardest:
            print(f"\n🛡️ 最难突破的防守球员: {hardest[0]}")
            print(f"  面对次数: {hardest[1]['面对次数']}")
            print(f"  成功突破: {hardest[1]['成功次数']}次")
    def visualize_stats(self):
        """可视化统计结果"""
        if not self.moves:
            print("暂无数据可可视化")
            return
        fig, axes = plt.subplots(2, 2, figsize=(12, 10))
        # 1. 成功/失败饼图
        ax1 = axes[0, 0]
        labels = ['成功晃过', '未成功']
        sizes = [self.get_successful_moves(), self.get_failed_moves()]
        colors = ['#2ecc71', '#e74c3c']
        ax1.pie(sizes, labels=labels, colors=colors, autopct='%1.1f%%', startangle=90)
        ax1.set_title('假动作成功率')
        # 2. 按类型柱状图
        ax2 = axes[0, 1]
        type_stats = self.stats_by_move_type()
        types = list(type_stats.keys())
        success_counts = [type_stats[t]['成功次数'] for t in types]
        fail_counts = [type_stats[t]['失败次数'] for t in types]
        x = np.arange(len(types))
        width = 0.35
        ax2.bar(x - width/2, success_counts, width, label='成功', color='#2ecc71')
        ax2.bar(x + width/2, fail_counts, width, label='失败', color='#e74c3c')
        ax2.set_xlabel('假动作类型')
        ax2.set_ylabel('次数')
        ax2.set_title('各类型假动作统计')
        ax2.set_xticks(x)
        ax2.set_xticklabels(types, rotation=45)
        ax2.legend()
        # 3. 按对手成功率
        ax3 = axes[1, 0]
        opp_stats = self.stats_by_opponent()
        opponents = list(opp_stats.keys())
        success_rates = [(opp_stats[o]['成功次数'] / opp_stats[o]['总次数'] * 100) 
                        for o in opponents]
        ax3.bar(opponents, success_rates, color='#3498db')
        ax3.set_xlabel('对手')
        ax3.set_ylabel('成功率 (%)')
        ax3.set_title('对每个对手的成功率')
        ax3.set_ylim(0, 100)
        ax3.tick_params(axis='x', rotation=45)
        # 4. 月度趋势
        ax4 = axes[1, 1]
        # 按日期排序
        sorted_moves = sorted(self.moves, key=lambda x: x['日期'])
        months = pd.Series([m['日期'] for m in sorted_moves])
        monthly_success = months.groupby(months).apply(
            lambda x: sum(1 for m in sorted_moves if m['日期'] == x.name and m['成功晃过'])
        )
        monthly_total = months.groupby(months).size()
        if len(monthly_total) > 1:
            ax4.plot(monthly_total.index, monthly_total.values, 'o-', label='总次数', color='#3498db')
            ax4.plot(monthly_success.index, monthly_success.values, 'o-', label='成功次数', color='#2ecc71')
            ax4.set_xlabel('日期')
            ax4.set_ylabel('次数')
            ax4.set_title('按日期统计')
            ax4.legend()
            ax4.tick_params(axis='x', rotation=45)
        else:
            ax4.text(0.5, 0.5, '数据不足', ha='center', va='center')
            ax4.set_title('按日期统计')
        plt.tight_layout()
        plt.show()
    def save_to_csv(self, filename="dribbling_stats.csv"):
        """保存数据到CSV文件"""
        if not self.moves:
            print("暂无数据可保存")
            return
        df = pd.DataFrame(self.moves)
        df.to_csv(filename, index=False, encoding='utf-8-sig')
        print(f"✅ 数据已保存到 {filename}")
# 使用示例
if __name__ == "__main__":
    # 创建球员实例
    player = DribblingAnalytics("张三")
    # 添加一些示例数据
    # 模拟一场比赛
    player.add_move("2024-01-15", "雷霆队", "背后变向", True, "迪克森", 1, 5)
    player.add_move("2024-01-15", "雷霆队", "胯下运球", True, "斯密斯", 2, 12)
    player.add_move("2024-01-15", "雷霆队", "转身过人", False, "迪克森", 3, 8)
    player.add_move("2024-01-15", "雷霆队", "交叉步", True, "约翰逊", 4, 15)
    # 第二场比赛
    player.add_move("2024-01-22", "勇士队", "背后变向", False, "库里", 1, 10)
    player.add_move("2024-01-22", "勇士队", "胯下运球", True, "汤普森", 2, 7)
    player.add_move("2024-01-22", "勇士队", "转身过人", True, "格林", 1, 3)
    # 第三场比赛
    player.add_move("2024-02-05", "湖人队", "背后变向", True, "詹姆斯", 2, 10)
    player.add_move("2024-02-05", "湖人队", "交叉步", True, "戴维斯", 1, 6)
    player.add_move("2024-02-05", "湖人队", "转身过人", False, "詹姆斯", 4, 15)
    # 生成报告
    print("🎮 正在生成统计报告...")
    player.generate_report()
    # 保存数据
    player.save_to_csv()
    # 可视化展示(需要matplotlib支持)
    try:
        player.visualize_stats()
    except:
        print("\n⚠️ 无法显示图表,可直接在Jupyter环境中查看")
    # 额外的分析
    print("\n🔍 更详细的分析:")
    # 找出成功率最高的假动作
    type_stats = player.stats_by_move_type()
    best_type = max(type_stats.items(), key=lambda x: x[1]['成功率'])
    print(f"最擅长的假动作: {best_type[0]} (成功率 {best_type[1]['成功率']:.1f}%)")
    # 按节次分析
    period_stats = {}
    for move in player.moves:
        period = move['节数']
        if period not in period_stats:
            period_stats[period] = {'总': 0, '成功': 0}
        period_stats[period]['总'] += 1
        if move['成功晃过']:
            period_stats[period]['成功'] += 1
    print("\n各节次表现:")
    for period, stats in sorted(period_stats.items()):
        rate = (stats['成功'] / stats['总'] * 100) if stats['总'] > 0 else 0
        print(f"  第{period}节: {stats['总']}次假动作, 成功{stats['成功']}次, 成功率{rate:.1f}%")

这个案例包含以下功能:

主要功能:

  1. 数据记录:可以记录每次假动作的详细信息

  2. 自动统计

    • 总动作次数
    • 成功晃过次数
    • 成功率计算
    • 按类型/对手/防守球员分类统计
  3. 可视化展示

    • 成功/失败比例饼图
    • 按假动作类型的柱状图
    • 对每个对手的成功率
    • 按时间的趋势图
  4. 报告生成:自动生成详细的分析报告

使用方式:

# 更简单的使用示例
player = DribblingAnalytics("李四")
# 快速记录
player.add_move("2024-03-01", "火箭队", "背后变向", True)
player.add_move("2024-03-01", "火箭队", "转身过人", False)
# 获取统计结果
print(f"成功次数: {player.get_successful_moves()}")
print(f"成功率: {player.get_success_rate():.1f}%")

输出示例:

📈 基本统计:
  总假动作次数: 10
  成功晃过: 7 次
  未成功: 3 次
  成功率: 70.0%
🎯 按假动作类型:
  背后变向:
    总次数: 3
    成功: 2
    成功率: 66.7%

这个系统可以帮助运动员或教练员追踪假动作的使用情况,找出最有效的技术动作,并针对弱点进行改进。

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