Spaces:
Sleeping
Sleeping
File size: 6,991 Bytes
1f7470c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 |
import pandas as pd
def check_columns(df, required_columns):
"""
Vérifie si les colonnes requises sont présentes dans le DataFrame.
Parameters:
- df (pd.DataFrame): Le DataFrame à vérifier.
- required_columns (list): Liste des noms de colonnes requis.
Returns:
- bool: True si toutes les colonnes sont présentes, sinon False.
"""
return all(column in df.columns for column in required_columns)
class StatsManager:
def __init__(self, events):
self.events = events
def calculate_stat(self, required_columns, func):
"""
Vérifie si les colonnes nécessaires sont présentes, puis applique la fonction de calcul si elles sont présentes.
Parameters:
- required_columns (list): Liste des colonnes requises.
- func (callable): Fonction à appliquer si les colonnes sont présentes.
Returns:
- tuple: Les résultats de la fonction si les colonnes sont présentes, sinon (None, None).
"""
if check_columns(self.events, required_columns):
return func(self.events)
else:
return None, None
def get_possession(self):
return self.calculate_stat(['possession_team'], self._calculate_possession)
def _calculate_possession(self, events):
possession_counts = events['possession_team'].value_counts()
if len(possession_counts) < 2:
return None, None
total_possession = possession_counts.iloc[0] + possession_counts.iloc[1]
home_possession = round((possession_counts.iloc[0] / total_possession) * 100, 1)
away_possession = round((possession_counts.iloc[1] / total_possession) * 100, 1)
return home_possession, away_possession
def get_total_xg(self):
return self.calculate_stat(['shot_statsbomb_xg', 'team'], self._calculate_total_xg)
def _calculate_total_xg(self, events):
data = events[['shot_statsbomb_xg', 'team']].dropna(subset=['shot_statsbomb_xg'])
if data.empty:
return None, None
data = data.groupby('team')['shot_statsbomb_xg'].sum()
if len(data) < 2:
return None, None
return round(data.iloc[0], 2), round(data.iloc[1], 2)
def get_total_shots(self):
return self.calculate_stat(['shot_statsbomb_xg', 'team'], self._calculate_total_shots)
def _calculate_total_shots(self, events):
data = events[['shot_statsbomb_xg', 'team']].dropna(subset=['shot_statsbomb_xg'])
if data.empty:
return None, None
shot_counts = data.groupby('team').count()['shot_statsbomb_xg']
if len(shot_counts) < 2:
return None, None
return shot_counts.iloc[0], shot_counts.iloc[1]
def get_total_shots_off_target(self):
return self.calculate_stat(['shot_outcome', 'team'], self._calculate_total_shots_off_target)
def _calculate_total_shots_off_target(self, events):
off_target_outcomes = ['Off T', 'Blocked', 'Missed']
data = events[events['shot_outcome'].isin(off_target_outcomes)]
if data.empty:
return None, None
off_target_counts = data.groupby('team').size()
if len(off_target_counts) < 2:
return None, None
return off_target_counts.iloc[0], off_target_counts.iloc[1]
def get_total_shots_on_target(self):
return self.calculate_stat(['shot_outcome', 'team'], self._calculate_total_shots_on_target)
def _calculate_total_shots_on_target(self, events):
on_target_outcomes = ['Goal', 'Saved', 'Saved To Post', 'Shot Saved Off Target']
data = events[events['shot_outcome'].isin(on_target_outcomes)]
if data.empty:
return None, None
on_target_counts = data.groupby('team').size()
if len(on_target_counts) < 2:
return None, None
return on_target_counts.iloc[0], on_target_counts.iloc[1]
def get_total_passes(self):
return self.calculate_stat(['pass_end_location', 'team'], self._calculate_total_passes)
def _calculate_total_passes(self, events):
pass_counts = events.filter(regex='^pass_end_location|^team$').groupby('team').count()['pass_end_location']
if len(pass_counts) < 2:
return None, None
return pass_counts.iloc[0], pass_counts.iloc[1]
def get_successful_passes(self):
return self.calculate_stat(['pass_outcome', 'team'], self._calculate_successful_passes)
def _calculate_successful_passes(self, events):
home_passes, away_passes = self.get_total_passes()
unsuccessful_passes = events.filter(regex='^pass_outcome|^team$').groupby('team').count().reset_index()['pass_outcome']
if len(unsuccessful_passes) < 2:
return None, None
home_unsuccessful_passes = unsuccessful_passes.iloc[0]
away_unsuccessful_passes = unsuccessful_passes.iloc[1]
return home_passes - home_unsuccessful_passes, away_passes - away_unsuccessful_passes
def get_total_corners(self):
return self.calculate_stat(['pass_type', 'team'], self._calculate_total_corners)
def _calculate_total_corners(self, events):
corner_counts = events.filter(regex='^pass_type|^team$').query('pass_type == "Corner"').groupby('team').count()['pass_type']
if len(corner_counts) < 2:
return None, None
return corner_counts.iloc[0], corner_counts.iloc[1]
def get_total_fouls(self):
return self.calculate_stat(['type', 'team'], self._calculate_total_fouls)
def _calculate_total_fouls(self, events):
fouls = events[events['type'] == 'Foul Committed']
foul_counts = fouls.groupby('team').size()
if len(foul_counts) < 2:
return None, None
return foul_counts.iloc[0], foul_counts.iloc[1]
def get_total_yellow_cards(self):
return self.calculate_stat(['bad_behaviour_card', 'team'], self._calculate_total_yellow_cards)
def _calculate_total_yellow_cards(self, events):
yellow_card_counts = events.filter(regex='^bad_behaviour_card|^team$').query('bad_behaviour_card == "Yellow Card"').groupby('team').count()['bad_behaviour_card']
if len(yellow_card_counts) < 2:
return None, None
return yellow_card_counts.iloc[0], yellow_card_counts.iloc[1]
def get_total_red_cards(self):
return self.calculate_stat(['bad_behaviour_card', 'team'], self._calculate_total_red_cards)
def _calculate_total_red_cards(self, events):
red_card_counts = events.filter(regex='^bad_behaviour_card|^team$').query('bad_behaviour_card == "Red Card"').groupby('team').count()['bad_behaviour_card']
if len(red_card_counts) < 2:
return None, None
return red_card_counts.iloc[0], red_card_counts.iloc[1]
|