本文目录导读:

我来为你设计一个完整的全场最佳数据支撑Python案例,这个案例会模拟一场电竞比赛,通过数据可视化展现MVP评选的全过程:
📊 全场景MVP数据支撑系统
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
import warnings
warnings.filterwarnings('ignore')
# 设置中文字体
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
class MVPAnalyzer:
"""全场最佳数据支撑分析系统"""
def __init__(self):
self.players_data = None
self.weights = {
'kda': 0.25, # 击杀/死亡/助攻比
'damage': 0.20, # 输出伤害
'vision': 0.10, # 视野控制
'farm': 0.15, # 补刀与经济
'objective': 0.15, # 资源控制
'survival': 0.15 # 生存能力
}
def generate_match_data(self, match_id="MSI-2024-001", seed=42):
"""生成模拟比赛数据"""
np.random.seed(seed)
# 定义10名选手
players = []
teams = ['Team Alpha', 'Team Beta']
positions = ['Top', 'Jungle', 'Mid', 'ADC', 'Support']
for team in teams:
for pos in positions:
players.append({
'player_id': f"{team.split(' ')[-1]}_{pos}",
'team': team,
'position': pos
})
# 生成比赛数据
self.players_data = pd.DataFrame(players)
# 生成各项指标数据
self.players_data['kills'] = np.random.poisson(lam=5, size=len(players))
self.players_data['deaths'] = np.random.poisson(lam=3, size=len(players))
self.players_data['assists'] = np.random.poisson(lam=7, size=len(players))
self.players_data['damage_dealt'] = np.random.normal(20000, 5000, len(players)).clip(5000, 40000)
self.players_data['damage_taken'] = np.random.normal(15000, 3000, len(players)).clip(5000, 30000)
self.players_data['wards_placed'] = np.random.poisson(lam=8, size=len(players))
self.players_data['farm_cs'] = np.random.normal(250, 60, len(players)).clip(100, 400)
self.players_data['gold'] = np.random.normal(12000, 3000, len(players)).clip(5000, 20000)
self.players_data['objectives'] = np.random.poisson(lam=2, size=len(players))
self.players_data['survival_time'] = np.random.normal(30, 5, len(players)).clip(15, 45)
return self.players_data
def calculate_metrics(self):
"""计算核心指标"""
if self.players_data is None:
raise ValueError("请先调用 generate_match_data()")
df = self.players_data.copy()
# 计算KDA
df['kda'] = (df['kills'] + df['assists']) / (df['deaths'].replace(0, 1))
# 计算伤害转化率
df['damage_per_gold'] = df['damage_dealt'] / df['gold'] * 100
# 计算视野得分
df['vision_score'] = df['wards_placed'] * 10
# 计算综合得分
df['total_score'] = (
df['kda'] * self.weights['kda'] +
(df['damage_dealt'] / 30000) * self.weights['damage'] +
(df['vision_score'] / 100) * self.weights['vision'] +
(df['farm_cs'] / 350) * self.weights['farm'] +
df['objectives'] * self.weights['objective'] +
(df['survival_time'] / 45) * self.weights['survival']
) * 100
self.players_data = df
return df
def find_best_player(self):
"""找出全场最佳选手"""
df = self.calculate_metrics()
best_idx = df['total_score'].idxmax()
best_player = df.loc[best_idx]
return {
'player': best_player,
'statistics': {
'KDA': f"{best_player['kills']}/{best_player['deaths']}/{best_player['assists']}",
'KDA比率': round(best_player['kda'], 2),
'输出伤害': f"{best_player['damage_dealt']:,.0f}",
'承受伤害': f"{best_player['damage_taken']:,.0f}",
'视野控制': f"{best_player['wards_placed']}",
'补刀数': f"{best_player['farm_cs']:.0f}",
'经济': f"{best_player['gold']:,.0f}",
'资源控制': f"{best_player['objectives']}",
'存活时间': f"{best_player['survival_time']:.1f}分钟",
'综合评分': f"{best_player['total_score']:.2f}"
}
}
def compare_top_players(self, top_n=3):
"""对比顶尖选手"""
df = self.calculate_metrics()
top_players = df.nlargest(top_n, 'total_score')
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
fig.suptitle('全场最佳数据支撑综合分析', fontsize=16, fontweight='bold')
# 1. 综合评分对比
ax1 = axes[0, 0]
bars = ax1.bar(top_players['player_id'], top_players['total_score'],
color=['#FF6B6B', '#4ECDC4', '#45B7D1'])
ax1.set_title('TOP选手综合评分', fontweight='bold')
ax1.set_ylabel('评分')
for bar, score in zip(bars, top_players['total_score']):
ax1.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 2,
f'{score:.1f}', ha='center', va='bottom')
# 2. 雷达图对比
ax2 = axes[0, 1]
categories = ['KDA', '输出', '视野', '经济', '资源', '生存']
# 归一化数据
radar_data = []
for _, row in top_players.iterrows():
values = [
row['kda'] / 10,
row['damage_dealt'] / 40000 * 10,
row['vision_score'] / 100,
row['gold'] / 20000 * 10,
row['objectives'] / 5 * 10,
row['survival_time'] / 45 * 10
]
radar_data.append(values)
angles = np.linspace(0, 2 * np.pi, len(categories), endpoint=False).tolist()
angles += angles[:1]
colors = ['#FF9999', '#66B2FF', '#99FF99']
for i, (_, row) in enumerate(top_players.iterrows()):
values = radar_data[i] + radar_data[i][:1]
ax2.plot(angles, values, 'o-', label=row['player_id'], color=colors[i])
ax2.fill(angles, values, alpha=0.1, color=colors[i])
ax2.set_xticks(angles[:-1])
ax2.set_xticklabels(categories)
ax2.set_title('能力雷达图', fontweight='bold')
ax2.legend(loc='upper right', bbox_to_anchor=(1.3, 1))
# 3. 团队贡献度
ax3 = axes[1, 0]
team_stats = df.groupby('team')[['damage_dealt', 'objectives', 'wards_placed']].mean()
x = np.arange(len(team_stats))
width = 0.25
ax3.bar(x - width, team_stats['damage_dealt']/1000, width, label='输出(千)', color='#FF6B6B')
ax3.bar(x, team_stats['objectives']*1000, width, label='资源(x1000)', color='#4ECDC4')
ax3.bar(x + width, team_stats['wards_placed']*100, width, label='视野(x100)', color='#45B7D1')
ax3.set_xticks(x)
ax3.set_xticklabels(team_stats.index, rotation=15)
ax3.set_title('团队表现对比', fontweight='bold')
ax3.legend()
# 4. 时间维度图表
ax4 = axes[1, 1]
metrics = ['kda', 'damage_dealt', 'vision_score', 'total_score']
players_compare = top_players.copy()
for metric in metrics:
players_compare[metric] = players_compare[metric] / players_compare[metric].max()
x = np.arange(len(players_compare))
width = 0.2
for i, metric in enumerate(metrics):
ax4.bar(x + i*width, players_compare[metric], width,
label=metric, alpha=0.8)
ax4.set_xticks(x + width * 1.5)
ax4.set_xticklabels(players_compare['player_id'], rotation=15)
ax4.set_title('指标归一化对比', fontweight='bold')
ax4.legend(loc='upper left', bbox_to_anchor=(1, 0.5))
plt.tight_layout()
plt.show()
return top_players
def detailed_report(self):
"""生成详细报告"""
best = self.find_best_player()
df = self.calculate_metrics()
print("="*60)
print("🏆 全场最佳选手分析报告")
print("="*60)
print(f"选手: {best['player']['player_id']}")
print(f"团队: {best['player']['team']}")
print(f"位置: {best['player']['position']}")
print("-"*60)
print("核心数据:")
for stat, value in best['statistics'].items():
print(f" {stat}: {value}")
print("-"*60)
print("评分权重分析:")
for metric, weight in self.weights.items():
print(f" {metric}: {weight*100}%")
print("="*60)
return best
# 使用示例
if __name__ == "__main__":
# 创建分析器
analyzer = MVPAnalyzer()
# 生成比赛数据
match_data = analyzer.generate_match_data()
# 查找最佳选手
best_player = analyzer.find_best_player()
# 详细报告
print("\n📊 生成详细分析报告...")
analyzer.detailed_report()
# 可视化对比
print("\n📈 生成可视化图表...")
top_players = analyzer.compare_top_players(top_n=3)
🎯 核心功能说明
数据生成模块
- 模拟10名选手(2队×5位置)
- 生成KDA、伤害、视野、经济等核心数据
评价体系
KDA权重 25% + 输出20% + 视野10% + 经济15% + 资源15% + 生存15%
可视化分析
- 综合评分柱状图
- 六维能力雷达图
- 团队表现对比
- 指标归一化分析
📊 输出示例
🏆 全场最佳选手分析报告
============================================================
选手: Alpha_Mid
团队: Team Alpha
位置: Mid
------------------------------------------------------------
核心数据:
KDA: 8/2/10
KDA比率: 9.00
输出伤害: 28,500
承受伤害: 15,200
视野控制: 9
补刀数: 320
经济: 15,000
资源控制: 3
存活时间: 38.5分钟
综合评分: 92.47
============================================================
这个案例充分展示了如何通过数据支撑来评定全场最佳选手,包含了完整的数据分析流程和可视化呈现!