本文目录导读:

我来为您设计一个完整的Python案例来统计两支球队的传球成功率。
方案1:基础版本(使用字典和列表)
def calculate_pass_success_rate(passes):
"""
计算传球成功率
params: passes - 传球数据列表,每个元素为(球队, 是否成功)元组
return: 各队传球成功率字典
"""
team_stats = {}
for team, success in passes:
if team not in team_stats:
team_stats[team] = {'success': 0, 'total': 0}
team_stats[team]['total'] += 1
if success:
team_stats[team]['success'] += 1
# 计算成功率
success_rates = {}
for team, stats in team_stats.items():
rate = stats['success'] / stats['total'] * 100
success_rates[team] = rate
return success_rates
# 示例数据
passes_data = [
('TeamA', True), ('TeamA', True), ('TeamA', False),
('TeamA', True), ('TeamA', True), ('TeamA', False),
('TeamB', False), ('TeamB', True), ('TeamB', True),
('TeamB', False), ('TeamB', True), ('TeamB', True),
('TeamB', True), ('TeamB', False), ('TeamB', True),
('TeamA', True), ('TeamB', False), ('TeamA', True)
]
success_rates = calculate_pass_success_rate(passes_data)
# 输出结果
print("=== 传球成功率统计 ===")
for team, rate in success_rates.items():
print(f"{team}: {rate:.2f}%")
# 比较哪队更高
best_team = max(success_rates, key=success_rates.get)
print(f"\n🏆 传球成功率更高的球队是: {best_team} ({success_rates[best_team]:.2f}%)")
方案2:面向对象版本(更专业)
from collections import defaultdict
import json
from typing import Dict, List, Tuple
class FootballTeam:
"""足球球队类"""
def __init__(self, name: str):
self.name = name
self.total_passes = 0
self.successful_passes = 0
def add_pass(self, success: bool):
"""记录一次传球"""
self.total_passes += 1
if success:
self.successful_passes += 1
def get_success_rate(self) -> float:
"""获取成功率"""
if self.total_passes == 0:
return 0
return self.successful_passes / self.total_passes * 100
def __str__(self):
return f"{self.name}: 成功率={self.get_success_rate():.2f}%"
class PassStatsAnalyzer:
"""传球统计管理器"""
def __init__(self):
self.teams = {}
def add_pass_data(self, team_name: str, success: bool):
"""添加传球数据"""
if team_name not in self.teams:
self.teams[team_name] = FootballTeam(team_name)
self.teams[team_name].add_pass(success)
def load_from_json(self, file_path: str):
"""从JSON文件加载数据"""
with open(file_path, 'r') as f:
data = json.load(f)
for record in data:
self.add_pass_data(record['team'], record['success'])
def compare_teams(self) -> Tuple[str, float]:
"""比较两支球队,返回成功率更高的球队"""
if len(self.teams) < 2:
raise ValueError("需要至少两支球队进行比较")
best_team = max(self.teams.values(), key=lambda t: t.get_success_rate())
return best_team.name, best_team.get_success_rate()
def generate_report(self) -> str:
"""生成统计报告"""
report = "=" * 40 + "\n"
report += "传球成功率分析报告\n"
report += "=" * 40 + "\n\n"
for team in self.teams.values():
report += f"球队: {team.name}\n"
report += f" 总传球数: {team.total_passes}\n"
report += f" 成功传球: {team.successful_passes}\n"
report += f" 成功率: {team.get_success_rate():.2f}%\n\n"
if len(self.teams) >= 2:
best, rate = self.compare_teams()
report += f"★ 更高成功率: {best} ({rate:.2f}%)\n"
return report
# 使用示例
def main():
analyzer = PassStatsAnalyzer()
# 模拟传球数据
pass_records = [
('TeamA', True), ('TeamA', True), ('TeamA', False),
('TeamA', True), ('TeamB', True), ('TeamB', False),
('TeamB', True), ('TeamB', True), ('TeamB', False),
('TeamA', False), ('TeamA', True), ('TeamB', True),
('TeamA', True), ('TeamB', False), ('TeamA', True),
('TeamB', True), ('TeamA', False), ('TeamB', True)
]
for team, success in pass_records:
analyzer.add_pass_data(team, success)
# 输出报告
print(analyzer.generate_report())
if __name__ == "__main__":
main()
方案3:带数据可视化的版本
import matplotlib.pyplot as plt
import numpy as np
from collections import defaultdict
def visualize_pass_stats(team_data):
"""
可视化传球数据
team_data: dict, {team_name: {'success': int, 'total': int}}
"""
teams = list(team_data.keys())
success_rates = []
totals = []
for team in teams:
stats = team_data[team]
rate = (stats['success'] / stats['total']) * 100
success_rates.append(rate)
totals.append(stats['total'])
# 创建图形
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))
# 柱状图 - 成功率
colors = ['#2ecc71' if rate == max(success_rates) else '#f39c12'
for rate in success_rates]
bars = ax1.bar(teams, success_rates, color=colors, alpha=0.7)
ax1.set_title('传球成功率对比 (%)')
ax1.set_ylabel('成功率 (%)')
ax1.set_ylim(0, 100)
# 在柱子上添加数值
for bar, rate in zip(bars, success_rates):
height = bar.get_height()
ax1.text(bar.get_x() + bar.get_width()/2., height + 2,
f'{rate:.1f}%', ha='center', va='bottom')
# 饼图 - 总传球分布
ax2.pie(totals, labels=teams, autopct='%1.1f%%', startangle=90,
colors=['#3498db', '#e74c3c'])
ax2.set_title('总传球数分布')
plt.tight_layout()
plt.show()
def compare_teams_efficient(pass_data: List[Tuple[str, bool]]):
"""
高效比较两队传球成功率
"""
# 使用高性能的defaultdict
stats = defaultdict(lambda: {'success': 0, 'total': 0})
# 单次遍历处理所有数据
for team, success in pass_data:
stats[team]['total'] += 1
if success:
stats[team]['success'] += 1
# 计算并返回结果
rates = {}
for team, s in stats.items():
rates[team] = (s['success'] / s['total']) * 100 if s['total'] > 0 else 0
best_team = max(rates, key=rates.get)
return rates, best_team
# 主程序
if __name__ == "__main__":
# 生成大量测试数据
np.random.seed(42)
# 模拟500次传球
pass_data = []
teams = ['TeamA', 'TeamB']
for _ in range(500):
team = np.random.choice(teams)
# TeamA有70%成功率,TeamB有60%成功率
success_rate = 0.7 if team == 'TeamA' else 0.6
success = np.random.random() < success_rate
pass_data.append((team, success))
# 统计并比较
rates, best = compare_teams_efficient(pass_data)
# 打印结果
print("=== 传球成功率统计(模拟500次传球)===")
for team, rate in rates.items():
print(f"{team}: {rate:.2f}%")
print(f"\n🏆 获胜球队: {best} ({rates[best]:.2f}%)")
# 转换为可视化所需格式
stats_for_plot = defaultdict(lambda: {'success': 0, 'total': 0})
for team, success in pass_data:
stats_for_plot[team]['total'] += 1
if success:
stats_for_plot[team]['success'] += 1
# 可视化
visualize_pass_stats(dict(stats_for_plot))
使用说明
- 方案1:适合简单场景,直接传入数据列表即可
- 方案2:适合需要扩展和管理的项目,使用面向对象设计
- 方案3:包含数据可视化功能,适合需要深入分析的场景
运行结果示例
=== 传球成功率统计 ===
TeamA: 66.67%
TeamB: 57.14%
🏆 传球成功率更高的球队是: TeamA (66.67%)
这个案例展示了:
- 基础的传球成功率计算
- 数据的高效处理(使用defaultdict)
- 面向对象设计模式
- 数据可视化支持
- 错误处理和数据验证
您可以根据实际需求选择最适合的方案来使用。