本文目录导读:

我来创建一个统计假动作晃过防守次数的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}%")
这个案例包含以下功能:
主要功能:
-
数据记录:可以记录每次假动作的详细信息
-
自动统计:
- 总动作次数
- 成功晃过次数
- 成功率计算
- 按类型/对手/防守球员分类统计
-
可视化展示:
- 成功/失败比例饼图
- 按假动作类型的柱状图
- 对每个对手的成功率
- 按时间的趋势图
-
报告生成:自动生成详细的分析报告
使用方式:
# 更简单的使用示例
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%
这个系统可以帮助运动员或教练员追踪假动作的使用情况,找出最有效的技术动作,并针对弱点进行改进。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播