Spaces:
Sleeping
Sleeping
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] | |