我来为您创建一个统计门将扑救次数的Python案例,看看谁更"忙"。

import matplotlib.pyplot as plt
import numpy as np
from datetime import datetime
# 创建门将数据
class Goalkeeper:
def __init__(self, name, team):
self.name = name
self.team = team
self.saves = [] # 每周扑救次数
self.matches = 0
self.total_saves = 0
def add_match_saves(self, saves_count):
"""添加一场比赛的扑救次数"""
self.saves.append(saves_count)
self.matches += 1
self.total_saves += saves_count
def get_avg_saves(self):
"""获取平均每场扑救次数"""
if self.matches == 0:
return 0
return self.total_saves / self.matches
def get_max_saves(self):
"""获取单场最高扑救次数"""
return max(self.saves) if self.saves else 0
def get_min_saves(self):
"""获取单场最低扑救次数"""
return min(self.saves) if self.saves else 0
# 创建门将对象并添加数据
def create_goalkeeper_data():
# 创建门将
goalkeepers = [
Goalkeeper("王大雷", "山东泰山"),
Goalkeeper("颜骏凌", "上海海港"),
Goalkeeper("刘殿座", "武汉三镇"),
Goalkeeper("韩佳奇", "北京国安")
]
# 模拟10场比赛的扑救数据
match_data = {
"王大雷": [5, 3, 6, 4, 7, 2, 5, 6, 4, 3],
"颜骏凌": [2, 3, 4, 2, 3, 5, 2, 3, 4, 2],
"刘殿座": [4, 5, 3, 6, 4, 5, 3, 6, 5, 4],
"韩佳奇": [6, 7, 5, 8, 6, 7, 5, 6, 7, 8]
}
# 为每个门将添加数据
for gk in goalkeepers:
if gk.name in match_data:
for saves in match_data[gk.name]:
gk.add_match_saves(saves)
return goalkeepers
# 统计分析函数
def analyze_goalkeepers(goalkeepers):
"""分析门将数据"""
print("=" * 60)
print("门将扑救数据统计分析")
print("=" * 60)
print("\n【基本统计】")
print("-" * 40)
for gk in goalkeepers:
print(f"\n{gk.name} ({gk.team}):")
print(f" 出场场次: {gk.matches}场")
print(f" 总扑救次数: {gk.total_saves}次")
print(f" 平均每场扑救: {gk.get_avg_saves():.2f}次")
print(f" 单场最高扑救: {gk.get_max_saves()}次")
print(f" 单场最低扑救: {gk.get_min_saves()}次")
print(f" 扑救稳定性: {np.std(gk.saves):.2f}")
# 比较谁更忙
def find_busiest_goalkeeper(goalkeepers):
"""找出最忙的门将"""
print("\n【谁更忙?】")
print("-" * 40)
# 按总扑救次数排序
by_total = sorted(goalkeepers, key=lambda x: x.total_saves, reverse=True)
print("按总扑救次数排名:")
for i, gk in enumerate(by_total, 1):
print(f" 第{i}名: {gk.name} - {gk.total_saves}次")
# 按平均扑救次数排序
by_avg = sorted(goalkeepers, key=lambda x: x.get_avg_saves(), reverse=True)
print("\n按平均每场扑救排名:")
for i, gk in enumerate(by_avg, 1):
print(f" 第{i}名: {gk.name} - {gk.get_avg_saves():.2f}次/场")
# 找出最忙的门将
busiest = max(goalkeepers, key=lambda x: x.total_saves)
busiest_avg = max(goalkeepers, key=lambda x: x.get_avg_saves())
print(f"\n🏆 总扑救次数最多: {busiest.name} ({busiest.total_saves}次)")
print(f"🏆 平均每场最忙: {busiest_avg.name} ({busiest_avg.get_avg_saves():.2f}次/场)")
# 可视化分析
def visualize_goalkeepers(goalkeepers):
"""可视化分析"""
fig, axes = plt.subplots(2, 2, figsize=(12, 10))
fig.suptitle('门将扑救数据分析', fontsize=16)
# 1. 总扑救次数柱状图
ax1 = axes[0, 0]
names = [gk.name for gk in goalkeepers]
totals = [gk.total_saves for gk in goalkeepers]
colors = ['#FF6B6B', '#4ECDC4', '#45B7D1', '#96CEB4']
bars = ax1.bar(names, totals, color=colors)
ax1.set_title('总扑救次数')
ax1.set_xlabel('球员')
ax1.set_ylabel('次数')
for bar, total in zip(bars, totals):
ax1.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.5,
str(total), ha='center', va='bottom')
# 2. 平均扑救次数比较
ax2 = axes[0, 1]
avgs = [gk.get_avg_saves() for gk in goalkeepers]
bars = ax2.bar(names, avgs, color=colors)
ax2.set_title('平均每场扑救次数')
ax2.set_xlabel('球员')
ax2.set_ylabel('次数/场')
for bar, avg in zip(bars, avgs):
ax2.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.1,
f'{avg:.2f}', ha='center', va='bottom')
# 3. 扑救次数走势图
ax3 = axes[1, 0]
for gk, color in zip(goalkeepers, colors):
matches = range(1, gk.matches + 1)
ax3.plot(matches, gk.saves, marker='o', label=gk.name, color=color)
ax3.set_title('每场比赛扑救走势')
ax3.set_xlabel('场次')
ax3.set_ylabel('扑救次数')
ax3.legend()
ax3.grid(True, alpha=0.3)
# 4. 盒须图(箱线图)
ax4 = axes[1, 1]
data = [gk.saves for gk in goalkeepers]
bp = ax4.boxplot(data, labels=names, patch_artist=True)
for patch, color in zip(bp['boxes'], colors):
patch.set_facecolor(color)
patch.set_alpha(0.7)
ax4.set_title('扑救次数分布')
ax4.set_xlabel('球员')
ax4.set_ylabel('扑救次数')
plt.tight_layout()
plt.show()
# 生成详细报告
def generate_report(goalkeepers):
"""生成分析报告"""
print("\n" + "=" * 60)
print("📊 详细分析报告")
print("=" * 60)
print("\n【球队防守压力分析】")
print("-" * 40)
for gk in goalkeepers:
avg = gk.get_avg_saves()
if avg >= 6:
pressure = "极高"
elif avg >= 4:
pressure = "较高"
elif avg >= 3:
pressure = "中等"
else:
pressure = "较低"
print(f"{gk.team} ({gk.name}): 防守压力{pressure}")
print("\n【扑救稳定性分析】")
print("-" * 40)
stability = []
for gk in goalkeepers:
std = np.std(gk.saves)
if std <= 1.5:
level = "稳定"
elif std <= 2.5:
level = "一般"
else:
level = "不稳定"
stability.append((gk.name, std, level))
print(f"{gk.name}: 波动{std:.2f},表现{level}")
print("\n【最佳表现场次】")
print("-" * 40)
all_matches = []
for gk in goalkeepers:
max_saves = gk.get_max_saves()
max_match = gk.saves.index(max_saves) + 1
all_matches.append((gk.name, max_saves, max_match))
all_matches.sort(key=lambda x: x[1], reverse=True)
for name, saves, match in all_matches:
print(f"{name}: 第{match}场扑救{saves}次")
print("\n【总评】")
print("-" * 40)
busiest_total = max(goalkeepers, key=lambda x: x.total_saves)
busiest_avg = max(goalkeepers, key=lambda x: x.get_avg_saves())
if busiest_total == busiest_avg:
print(f"🏆 最忙门将: {busiest_total.name}(总扑救{busiest_total.total_saves}次,场均{busiest_total.get_avg_saves():.2f}次)")
else:
print(f"总扑救最多: {busiest_total.name}")
print(f"场均最忙: {busiest_avg.name}")
# 主程序
def main():
# 创建数据
goalkeepers = create_goalkeeper_data()
# 分析并输出结果
analyze_goalkeepers(goalkeepers)
find_busiest_goalkeeper(goalkeepers)
generate_report(goalkeepers)
# 可视化
print("\n正在生成图表...")
try:
visualize_goalkeepers(goalkeepers)
except:
print("无法显示图表(请确保已安装matplotlib)")
# 额外的交互功能
print("\n【交互功能】")
print("-" * 40)
while True:
print("\n1. 查看单个门将详情")
print("2. 查看扑救排行")
print("3. 退出")
choice = input("请选择: ")
if choice == "1":
print("\n可选门将:")
for i, gk in enumerate(goalkeepers, 1):
print(f"{i}. {gk.name}")
try:
index = int(input("选择序号: ")) - 1
if 0 <= index < len(goalkeepers):
gk = goalkeepers[index]
print(f"\n{gk.name} 详细数据:")
print(f" 球队: {gk.team}")
print(f" 出战场次: {gk.matches}")
print(f" 总扑救: {gk.total_saves}")
print(f" 场均扑救: {gk.get_avg_saves():.2f}")
print(f" 最好表现: {gk.get_max_saves()}次")
print(f" 最差表现: {gk.get_min_saves()}次")
else:
print("无效的序号!")
except:
print("输入错误!")
elif choice == "2":
print("\n🔄 实时排行")
print("-" * 30)
ranked = sorted(goalkeepers, key=lambda x: x.total_saves, reverse=True)
for i, gk in enumerate(ranked, 1):
medal = {1: "🥇", 2: "🥈", 3: "🥉"}.get(i, "🏅")
print(f"{medal} {i}. {gk.name}: {gk.total_saves}次")
elif choice == "3":
print("感谢使用! 👋")
break
else:
print("无效选择,请重试!")
if __name__ == "__main__":
main()
这个程序的主要功能:
-
数据管理:创建门将类,记录每位门将的扑救数据
-
统计分析:
- 总扑救次数
- 平均每场扑救
- 单场最高/最低扑救
- 扑救稳定性
-
可视化分析:
- 柱状图比较总扑救和场均扑救
- 折线图展示每场比赛表现
- 箱线图展示扑救分布
-
交互功能:
- 查看单个门将详情
- 实时排行榜
运行后会输出详细的统计报告,并生成图表帮助直观比较哪些门将更"忙",您可以根据实际数据修改match_data字典来测试不同的数据场景。