根据python案例,Whoscored评分对比?

wen python案例 1

本文目录导读:

根据python案例,Whoscored评分对比?

  1. 完整的WhoScored评分对比分析案例
  2. 关键功能说明
  3. 注意事项

我来为你提供一个基于Python的WhoScored评分对比分析案例,由于WhoScored没有官方公开API,这里我将展示如何获取和处理数据,并构建一个评分对比系统。

完整的WhoScored评分对比分析案例

import requests
from bs4 import BeautifulSoup
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from datetime import datetime
import time
import json
from typing import Dict, List, Tuple
class WhoScoredAnalyzer:
    """WhoScored数据分析和对比工具"""
    def __init__(self):
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36'
        }
        self.base_url = "https://www.whoscored.com"
    def get_player_ratings(self, team_name: str, league: str = "Premier League") -> pd.DataFrame:
        """
        模拟获取球员评分数据(实际应用中需要爬取WhoScored)
        这里用模拟数据演示处理流程
        """
        # 模拟数据 - 实际应用中从WhoScored获取
        np.random.seed(hash(team_name) % 42)
        players = [
            '门将', '右后卫', '中后卫1', '中后卫2', '左后卫',
            '后腰', '中场1', '中场2', '右边锋', '中锋', '左边锋'
        ]
        # 生成模拟评分数据
        data = []
        for player in players:
            if '门将' in player:
                rating = np.random.normal(6.5, 0.3, 10)
            elif '后卫' in player:
                rating = np.random.normal(6.8, 0.4, 10)
            elif '中场' in player:
                rating = np.random.normal(7.0, 0.5, 10)
            else:
                rating = np.random.normal(7.2, 0.6, 10)
            # 确保分数在合理范围
            rating = np.clip(rating, 5.0, 9.0)
            for i, score in enumerate(rating):
                data.append({
                    '比赛序号': i+1,
                    '球队': team_name,
                    '球员': player,
                    '评分': round(score, 2),
                    '日期': datetime.now().strftime('%Y-%m-%d')
                })
        return pd.DataFrame(data)
    def calculate_average_ratings(self, team_data: pd.DataFrame) -> pd.DataFrame:
        """计算球员平均评分和稳定性"""
        ratings_stats = team_data.groupby('球员').agg({
            '评分': ['mean', 'std', 'min', 'max']
        }).round(2)
        ratings_stats.columns = ['平均评分', '标准差', '最低分', '最高分']
        ratings_stats['稳定性'] = ratings_stats['标准差'].apply(
            lambda x: '稳定' if x < 0.5 else ('一般' if x < 0.7 else '不稳定')
        )
        return ratings_stats.reset_index()
    def compare_teams(self, team1: str, team2: str, league: str = "Premier League") -> Dict:
        """对比两支球队的评分"""
        print(f"正在获取 {team1} 和 {team2} 的评分数据...")
        # 获取两组数据
        team1_data = self.get_player_ratings(team1, league)
        team2_data = self.get_player_ratings(team2, league)
        # 合并数据
        all_data = pd.concat([team1_data, team2_data], ignore_index=True)
        # 计算统计信息
        team1_stats = self.calculate_average_ratings(team1_data)
        team2_stats = self.calculate_average_ratings(team2_data)
        # 计算整体评级
        overall_team1 = team1_data['评分'].mean().round(2)
        overall_team2 = team2_data['评分'].mean().round(2)
        # 位置分析
        def position_analysis(data):
            positions = {
                '门将': ['门将'],
                '后卫': ['右后卫', '中后卫1', '中后卫2', '左后卫'],
                '中场': ['后腰', '中场1', '中场2'],
                '前锋': ['右边锋', '中锋', '左边锋']
            }
            result = {}
            for pos, players in positions.items():
                pos_data = data[data['球员'].isin(players)]
                result[pos] = pos_data['评分'].mean().round(2)
            return result
        comparison = {
            'team1': {
                'name': team1,
                'overall_rating': overall_team1,
                'position_analysis': position_analysis(team1_data),
                'best_player': team1_stats.loc[team1_stats['平均评分'].idxmax()]['球员'],
                'most_consistent': team1_stats.loc[team1_stats['标准差'].min()]['球员']
            },
            'team2': {
                'name': team2,
                'overall_rating': overall_team2,
                'position_analysis': position_analysis(team2_data),
                'best_player': team2_stats.loc[team2_stats['平均评分'].idxmax()]['球员'],
                'most_consistent': team2_stats.loc[team2_stats['标准差'].min()]['球员']
            },
            'data': {
                'team1_details': team1_stats,
                'team2_details': team2_stats,
                'all_data': all_data
            }
        }
        return comparison
    def visualize_comparison(self, comparison: Dict):
        """可视化对比结果"""
        fig, axes = plt.subplots(2, 3, figsize=(15, 10))
        fig.suptitle(f'WhoScored评分对比分析 - {comparison["team1"]["name"]} vs {comparison["team2"]["name"]}', fontsize=16)
        # 1. 总体评分对比
        ax1 = axes[0, 0]
        teams = [comparison['team1']['name'], comparison['team2']['name']]
        ratings = [comparison['team1']['overall_rating'], comparison['team2']['overall_rating']]
        colors = ['skyblue', 'lightcoral']
        bars = ax1.bar(teams, ratings, color=colors)
        ax1.set_title('总体评分对比')
        ax1.set_ylabel('平均评分')
        ax1.set_ylim(5, 8)
        for bar, rating in zip(bars, ratings):
            ax1.text(bar.get_x() + bar.get_width()/2, bar.get_height() + 0.1,
                    f'{rating:.2f}', ha='center', va='bottom')
        # 2. 位置对比
        ax2 = axes[0, 1]
        positions = list(comparison['team1']['position_analysis'].keys())
        team1_scores = list(comparison['team1']['position_analysis'].values())
        team2_scores = list(comparison['team2']['position_analysis'].values())
        x = np.arange(len(positions))
        width = 0.35
        ax2.bar(x - width/2, team1_scores, width, label=comparison['team1']['name'], color='skyblue')
        ax2.bar(x + width/2, team2_scores, width, label=comparison['team2']['name'], color='lightcoral')
        ax2.set_title('位置评分对比')
        ax2.set_ylabel('平均评分')
        ax2.set_xticks(x)
        ax2.set_xticklabels(positions)
        ax2.legend()
        # 3. 球员评分分布对比
        ax3 = axes[0, 2]
        all_data = comparison['data']['all_data']
        team1_data = all_data[all_data['球队'] == comparison['team1']['name']]['评分']
        team2_data = all_data[all_data['球队'] == comparison['team2']['name']]['评分']
        ax3.hist(team1_data, alpha=0.5, bins=15, color='skyblue', edgecolor='black', label=comparison['team1']['name'])
        ax3.hist(team2_data, alpha=0.5, bins=15, color='lightcoral', edgecolor='black', label=comparison['team2']['name'])
        ax3.set_title('评分分布对比')
        ax3.set_xlabel('评分')
        ax3.set_ylabel('频次')
        ax3.legend()
        # 4. 球员排名图
        ax4 = axes[1, 0]
        team1_details = comparison['data']['team1_details']
        team2_details = comparison['data']['team2_details']
        # 合并排名
        team1_details['球队'] = comparison['team1']['name']
        team2_details['球队'] = comparison['team2']['name']
        combined = pd.concat([team1_details, team2_details])
        combined = combined.sort_values('平均评分', ascending=True)
        y_pos = np.arange(len(combined))
        ax4.barh(y_pos, combined['平均评分'], color=['skyblue' if t == comparison['team1']['name'] else 'lightcoral' 
                                                       for t in combined['球队']])
        ax4.set_yticks(y_pos)
        ax4.set_yticklabels([f"{row['球员']} ({row['球队'][:5]}...)" for _, row in combined.iterrows()])
        ax4.set_xlabel('平均评分')
        ax4.set_title('球员评分排名对比')
        # 5. 稳定性对比
        ax5 = axes[1, 1]
        combined_std = combined.sort_values('标准差', ascending=True)
        y_pos5 = np.arange(len(combined_std))
        ax5.barh(y_pos5, combined_std['标准差'], color=['skyblue' if t == comparison['team1']['name'] else 'lightcoral' 
                                                         for t in combined_std['球队']])
        ax5.set_yticks(y_pos5)
        ax5.set_yticklabels([f"{row['球员']} ({row['球队'][:5]}...)" for _, row in combined_std.iterrows()])
        ax5.set_xlabel('标准差')
        ax5.set_title('球员稳定性对比')
        # 6. 雷达图
        ax6 = axes[1, 2]
        angles = np.linspace(0, 2 * np.pi, len(positions), endpoint=False).tolist()
        angles += angles[:1]
        team1_values = list(comparison['team1']['position_analysis'].values())
        team2_values = list(comparison['team2']['position_analysis'].values())
        team1_values += team1_values[:1]
        team2_values += team2_values[:1]
        ax6.plot(angles, team1_values, 'o-', linewidth=2, color='skyblue', label=comparison['team1']['name'])
        ax6.fill(angles, team1_values, alpha=0.25, color='skyblue')
        ax6.plot(angles, team2_values, 'o-', linewidth=2, color='lightcoral', label=comparison['team2']['name'])
        ax6.fill(angles, team2_values, alpha=0.25, color='lightcoral')
        ax6.set_xticks(angles[:-1])
        ax6.set_xticklabels(positions)
        ax6.set_ylim(6, 8)
        ax6.set_title('位置评分雷达图')
        ax6.legend(loc='lower right')
        plt.tight_layout()
        plt.show()
        return comparison
# 主程序
if __name__ == "__main__":
    # 创建分析器实例
    analyzer = WhoScoredAnalyzer()
    # 对比两支球队
    print("=" * 60)
    print("WhoScored评分对比分析工具")
    print("=" * 60)
    team1 = "曼城"
    team2 = "利物浦"
    try:
        # 获取对比数据
        comparison = analyzer.compare_teams(team1, team2)
        # 打印详细对比结果
        print(f"\n📊 总体评分对比:")
        print(f"  {team1}: {comparison['team1']['overall_rating']}")
        print(f"  {team2}: {comparison['team2']['overall_rating']}")
        print(f"\n⚽ 位置评分对比:")
        print(f"{'位置':<10} {team1:<12} {team2:<12} {'差值'}")
        print("-" * 40)
        for pos in comparison['team1']['position_analysis'].keys():
            t1_score = comparison['team1']['position_analysis'][pos]
            t2_score = comparison['team2']['position_analysis'][pos]
            diff = t1_score - t2_score
            print(f"{pos:<10} {t1_score:<12.2f} {t2_score:<12.2f} {diff:+.2f}")
        print(f"\n🏆 最佳球员:")
        print(f"  {team1}: {comparison['team1']['best_player']}")
        print(f"  {team2}: {comparison['team2']['best_player']}")
        print(f"\n📈 最稳定球员:")
        print(f"  {team1}: {comparison['team1']['most_consistent']}")
        print(f"  {team2}: {comparison['team2']['most_consistent']}")
        # 可视化
        print("\n正在生成可视化图表...")
        analyzer.visualize_comparison(comparison)
    except Exception as e:
        print(f"分析过程中出现错误: {e}")
    print("\n分析完成!")

关键功能说明

数据获取模块

  • 实际应用中需要爬取WhoScored网站的真实数据
  • 本案例使用模拟数据演示分析流程

评分计算与分析

  • 计算平均评分、标准差(稳定性)
  • 按位置(门将/后卫/中场/前锋)分类分析
  • 识别最佳球员和最稳定球员

可视化功能

  • 总体评分柱状图
  • 位置评分对比图
  • 评分分布直方图
  • 球员排名图
  • 稳定性对比图
  • 雷达图

实际应用扩展

如果需要爬取真实数据,可以这样实现:

def fetch_real_data(self, player_url: str):
    """从WhoScored获取真实数据"""
    try:
        response = requests.get(player_url, headers=self.headers)
        response.raise_for_status()
        soup = BeautifulSoup(response.content, 'html.parser')
        # 解析评分数据(需要根据页面结构调整)
        rating_elements = soup.find_all('div', class_='player-rating')
        ratings = []
        for elem in rating_elements:
            rating = float(elem.text.strip())
            ratings.append(rating)
        return ratings
    except Exception as e:
        print(f"获取数据失败: {e}")
        return None

注意事项

  1. 数据时效性:WhoScored评分会实时更新,需要定期刷新数据
  2. 样本量:建议至少使用10场比赛的数据
  3. 权重考虑:可根据比赛重要性(联赛/欧冠/杯赛)加权计算
  4. 对手实力:可结合对手强度调整评分

这个工具可用于球队能力评估、球员转会分析、战术安排参考等场景。

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