Source code for sportsipy.ncaaf.teams

import pandas as pd
import re
from .constants import PARSING_SCHEME
from ..decorators import float_property_decorator, int_property_decorator
from .. import utils
from .conferences import Conferences
from .ncaaf_utils import _retrieve_all_teams
from .roster import Roster
from .schedule import Schedule


[docs]class Team: """ An object containing all of a team's season information. Finds and parses all team stat information and identifiers, such as full and short names, and sets them as properties which can be directly read from for easy reference. If calling directly, the team's abbreviation needs to be passed. Otherwise, the Teams class will handle all arguments. Parameters ---------- team_name : string (optional) The name of the team to pull if being called directly. team_data : string (optional) A string containing all of the rows of stats for a given team. If multiple tables are being referenced, this will be comprised of multiple rows in a single string. team_conference : string (optional) A string of the team's conference abbreviation, such as 'big-12'. year : string (optional) The requested year to pull stats from. season_page : string (optional) Optionally specify the filename of a local file to use to pull data instead of downloading from sports-reference.com. This file should be of the Season page for the designated year. offensive_stats : string (optional) Optionally specify the filename of a local file to use to pull data instead of downloading from sports-reference.com. This file should be of the Offensive Stats page for the designated year. defensive_stats : string (optional) Optionally specify the filename of a local file to use to pull data instead of downloading from sports-reference.com. This file should be of the Defensive Stats page for the designated year. """ def __init__(self, team_name=None, team_data=None, team_conference=None, year=None, season_page=None, offensive_stats=None, defensive_stats=None): self._team_conference = team_conference self._year = year self._abbreviation = None self._name = None self._games = None self._wins = None self._losses = None self._win_percentage = None self._conference_wins = None self._conference_losses = None self._conference_win_percentage = None self._points_per_game = None self._points_against_per_game = None self._strength_of_schedule = None self._simple_rating_system = None self._pass_completions = None self._pass_attempts = None self._pass_completion_percentage = None self._pass_yards = None self._interceptions = None self._pass_touchdowns = None self._rush_attempts = None self._rush_yards = None self._rush_yards_per_attempt = None self._rush_touchdowns = None self._plays = None self._yards = None self._turnovers = None self._fumbles_lost = None self._yards_per_play = None self._pass_first_downs = None self._rush_first_downs = None self._first_downs_from_penalties = None self._first_downs = None self._penalties = None self._yards_from_penalties = None self._opponents_pass_completions = None self._opponents_pass_attempts = None self._opponents_pass_completion_percentage = None self._opponents_pass_yards = None self._opponents_interceptions = None self._opponents_pass_touchdowns = None self._opponents_rush_attempts = None self._opponents_rush_yards = None self._opponents_rush_yards_per_attempt = None self._opponents_rush_touchdowns = None self._opponents_plays = None self._opponents_yards = None self._opponents_turnovers = None self._opponents_fumbles_lost = None self._opponents_yards_per_play = None self._opponents_pass_first_downs = None self._opponents_rush_first_downs = None self._opponents_first_downs_from_penalties = None self._opponents_first_downs = None self._opponents_penalties = None self._opponents_yards_from_penalties = None if team_name: team_data = self._retrieve_team_data(year, team_name, season_page, offensive_stats, defensive_stats) conferences_dict = Conferences(year).team_conference self._team_conference = conferences_dict[team_name.lower()] self._parse_team_data(team_data) def __str__(self): """ Return the string representation of the class. """ return f'{self.name} ({self.abbreviation}) - {self._year}' def __repr__(self): """ Return the string representation of the class. """ return self.__str__() def _retrieve_team_data(self, year, team_name, season_page, offensive_stats, defensive_stats): """ Pull all stats for a specific team. By first retrieving a dictionary containing all information for all teams in the league, only select the desired team for a specific year and return only their relevant results. Parameters ---------- year : string A ``string`` of the requested year to pull stats from. team_name : string A ``string`` of the team's abbreviation, such as 'PURDUE' for the Purdue Boilermakers. season_page : string (optional) Optionally specify the filename of a local file to use to pull data instead of downloading from sports-reference.com. This file should be of the Season page for the designated year. offensive_stats : string (optional) Optionally specify the filename of a local file to use to pull data instead of downloading from sports-reference.com. This file should be of the Offensive Stats page for the designated year. defensive_stats : string (optional) Optionally specify the filename of a local file to use to pull data instead of downloading from sports-reference.com. This file should be of the Defensive Stats page for the designated year. Returns ------- PyQuery object Returns a PyQuery object containing all stats and information for the specified team. """ team_data_dict, year = _retrieve_all_teams(year, season_page, offensive_stats, defensive_stats) self._year = year team_data = team_data_dict[team_name]['data'] return team_data def _parse_team_data(self, team_data): """ Parses a value for every attribute. This function looks through every attribute and retrieves the value according to the parsing scheme and index of the attribute from the passed HTML data. Once the value is retrieved, the attribute's value is updated with the returned result. Note that this method is called directly once Team is invoked and does not need to be called manually. Parameters ---------- team_data : string A string containing all of the rows of stats for a given team. If multiple tables are being referenced, this will be comprised of multiple rows in a single string. """ for field in self.__dict__: if field == '_year' or \ field == '_team_conference': continue value = utils._parse_field(PARSING_SCHEME, team_data, str(field)[1:]) setattr(self, field, value) @property def dataframe(self): """ Returns a pandas DataFrame containing all other class properties and values. The index for the DataFrame is the string abbreviation of the team, such as 'PURDUE'. """ fields_to_include = { 'abbreviation': self.abbreviation, 'conference': self.conference, 'conference_losses': self.conference_losses, 'conference_win_percentage': self.conference_win_percentage, 'conference_wins': self.conference_wins, 'first_downs': self.first_downs, 'opponents_first_downs': self.opponents_first_downs, 'first_downs_from_penalties': self.first_downs_from_penalties, 'opponents_first_downs_from_penalties': self.opponents_first_downs_from_penalties, 'fumbles_lost': self.fumbles_lost, 'opponents_fumbles_lost': self.opponents_fumbles_lost, 'games': self.games, 'interceptions': self.interceptions, 'opponents_interceptions': self.opponents_interceptions, 'losses': self.losses, 'name': self.name, 'pass_attempts': self.pass_attempts, 'opponents_pass_attempts': self.opponents_pass_attempts, 'pass_completion_percentage': self.pass_completion_percentage, 'opponents_pass_completion_percentage': self.opponents_pass_completion_percentage, 'pass_completions': self.pass_completions, 'opponents_pass_completions': self.opponents_pass_completions, 'pass_first_downs': self.pass_first_downs, 'opponents_pass_first_downs': self.opponents_pass_first_downs, 'pass_touchdowns': self.pass_touchdowns, 'opponents_pass_touchdowns': self.opponents_pass_touchdowns, 'pass_yards': self.pass_yards, 'opponents_pass_yards': self.opponents_pass_yards, 'penalties': self.penalties, 'opponents_penalties': self.opponents_penalties, 'plays': self.plays, 'opponents_plays': self.opponents_plays, 'points_against_per_game': self.points_against_per_game, 'points_per_game': self.points_per_game, 'rush_attempts': self.rush_attempts, 'opponents_rush_attempts': self.opponents_rush_attempts, 'rush_first_downs': self.rush_first_downs, 'opponents_rush_first_downs': self.opponents_rush_first_downs, 'rush_touchdowns': self.rush_touchdowns, 'opponents_rush_touchdowns': self.opponents_rush_touchdowns, 'rush_yards': self.rush_yards, 'opponents_rush_yards': self.opponents_rush_yards, 'rush_yards_per_attempt': self.rush_yards_per_attempt, 'opponents_rush_yards_per_attempt': self.opponents_rush_yards_per_attempt, 'simple_rating_system': self.simple_rating_system, 'strength_of_schedule': self.strength_of_schedule, 'turnovers': self.turnovers, 'opponents_turnovers': self.opponents_turnovers, 'win_percentage': self.win_percentage, 'wins': self.wins, 'yards': self.yards, 'opponents_yards': self.opponents_yards, 'yards_from_penalties': self.yards_from_penalties, 'opponents_yards_from_penalties': self.opponents_yards_from_penalties, 'yards_per_play': self.yards_per_play, 'opponents_yards_per_play': self.opponents_yards_per_play } return pd.DataFrame([fields_to_include], index=[self._abbreviation]) @property def conference(self): """ Returns a ``string`` of the team's conference abbreviation, such as 'big-12' for the Big 12 Conference. """ return self._team_conference @property def abbreviation(self): """ Returns a ``string`` of the team's short name, such as 'PURDUE' for the Purdue Boilermakers. """ return self._abbreviation @property def schedule(self): """ Returns an instance of the Schedule class containing the team's complete schedule for the season. """ return Schedule(self._abbreviation, self._year) @property def roster(self): """ Returns an instance of the Roster class containing all players for the team during the season with all career stats. """ return Roster(self._abbreviation, self._year) @property def name(self): """ Returns a ``string`` of the team's full name, such as 'Purdue Boilermakers'. """ return self._name @int_property_decorator def games(self): """ Returns an ``int`` of the total number of games the team has played during the season. """ return self._games @int_property_decorator def wins(self): """ Returns an ``int`` of the total number of games the team won during the season. """ return self._wins @int_property_decorator def losses(self): """ Returns an ``int`` of the total number of games the team lost during the season. """ return self._losses @float_property_decorator def win_percentage(self): """ Returns a ``float`` of the percentage of wins divided by the number of games played during the season. Percentage ranges from 0-1. """ return self._win_percentage @int_property_decorator def conference_wins(self): """ Returns an ``int`` of the total number of conference games the team won during the season. """ return self._conference_wins @int_property_decorator def conference_losses(self): """ Returns an ``int`` of the total number of conference games the team lost during the season. """ return self._conference_losses @float_property_decorator def conference_win_percentage(self): """ Returns a ``float`` of the percentage of conference wins divided by the number of conference games played during the season. Percentage ranges from 0-1. """ return self._conference_win_percentage @float_property_decorator def points_per_game(self): """ Returns a ``float`` of the average number of points scored by the team per game. """ return self._points_per_game @float_property_decorator def points_against_per_game(self): """ Returns a ``float`` of the average number of points conceded per game. """ return self._points_against_per_game @float_property_decorator def strength_of_schedule(self): """ Returns a ``float`` of the team's strength of schedule based on the number of points above or below average. An average difficulty schedule is denoted with 0.0 while a negative score indicates a comparatively easy schedule. """ return self._strength_of_schedule @float_property_decorator def simple_rating_system(self): """ Returns a ``float`` of the team's relative strength based on the average margin of victory and the strength of schedule. An average team is denoted with 0.0 while a negative score indicates a comparatively weak team. """ return self._simple_rating_system @float_property_decorator def pass_completions(self): """ Returns a ``float`` of the average number of completed passes per game. """ return self._pass_completions @float_property_decorator def opponents_pass_completions(self): """ Returns a ``float`` of the opponents' average number of completed passes per game. """ return self._opponents_pass_completions @float_property_decorator def pass_attempts(self): """ Returns a ``float`` of the average number of passes that are attempted per game. """ return self._pass_attempts @float_property_decorator def opponents_pass_attempts(self): """ Returns a ``float`` of the opponents' average number of passes that are attempted per game. """ return self._opponents_pass_attempts @float_property_decorator def pass_completion_percentage(self): """ Returns a ``float`` of the percentage of completed passes per game. Percentage ranges from 0-100. """ return self._pass_completion_percentage @float_property_decorator def opponents_pass_completion_percentage(self): """ Returns a ``float`` of the opponents' percentage of completed passes per game. Percentage ranges from 0-100. """ return self._opponents_pass_completion_percentage @float_property_decorator def pass_yards(self): """ Returns a ``float`` of the average number of yards gained from passing per game. """ return self._pass_yards @float_property_decorator def opponents_pass_yards(self): """ Returns a ``float`` of the opponents' average number of yards gained from passing per game. """ return self._opponents_pass_yards @float_property_decorator def interceptions(self): """ Returns a ``float`` of the average number of interceptions thrown per game. """ return self._interceptions @float_property_decorator def opponents_interceptions(self): """ Returns a ``float`` of the opponents' average number of interceptions thrown per game. """ return self._opponents_interceptions @float_property_decorator def pass_touchdowns(self): """ Returns a ``float`` of the average number of passing touchdowns scored per game. """ return self._pass_touchdowns @float_property_decorator def opponents_pass_touchdowns(self): """ Returns a ``float`` of the opponents' average number of passing touchdowns scored per game. """ return self._opponents_pass_touchdowns @float_property_decorator def rush_attempts(self): """ Returns a ``float`` of the average number of rushing plays per game. """ return self._rush_attempts @float_property_decorator def opponents_rush_attempts(self): """ Returns a ``float`` of the opponents' average number of rushing plays per game. """ return self._opponents_rush_attempts @float_property_decorator def rush_yards(self): """ Returns a ``float`` of the average number of yards gained from rushing per game. """ return self._rush_yards @float_property_decorator def opponents_rush_yards(self): """ Returns a ``float`` of the opponents' average number of yards gained from rushing per game. """ return self._opponents_rush_yards @float_property_decorator def rush_yards_per_attempt(self): """ Returns a ``float`` of the average number of yards gained per rushing attempt per game. """ return self._rush_yards_per_attempt @float_property_decorator def opponents_rush_yards_per_attempt(self): """ Returns a ``float`` of the opponents' average number of yards gained per rushing attempt per game. """ return self._opponents_rush_yards_per_attempt @float_property_decorator def rush_touchdowns(self): """ Returns a ``float`` of the average number of rushing touchdowns scored per game. """ return self._rush_touchdowns @float_property_decorator def opponents_rush_touchdowns(self): """ Returns a ``float`` of the opponents' average number of rushing touchdowns scored per game. """ return self._opponents_rush_touchdowns @float_property_decorator def plays(self): """ Returns a ``float`` of the average number of offensive plays per game. """ return self._plays @float_property_decorator def opponents_plays(self): """ Returns a ``float`` of the opponents' average number of offensive plays per game. """ return self._opponents_plays @float_property_decorator def yards(self): """ Returns a ``float`` of the average number of yards gained per game. """ return self._yards @float_property_decorator def opponents_yards(self): """ Returns a ``float`` of the opponents' average number of yards gained per game. """ return self._opponents_yards @float_property_decorator def turnovers(self): """ Returns a ``float`` of the average number of turnovers per game. """ return self._turnovers @float_property_decorator def opponents_turnovers(self): """ Returns a ``float`` of the opponents' average number of turnovers per game. """ return self._opponents_turnovers @float_property_decorator def fumbles_lost(self): """ Returns a ``float`` of the average number of fumbles per game. """ return self._fumbles_lost @float_property_decorator def opponents_fumbles_lost(self): """ Returns a ``float`` of the opponents' average number of fumbles per game. """ return self._opponents_fumbles_lost @float_property_decorator def yards_per_play(self): """ Returns a ``float`` of the average number of yards gained per play. """ return self._yards_per_play @float_property_decorator def opponents_yards_per_play(self): """ Returns a ``float`` of the opponents' average number of yards gained per play. """ return self._opponents_yards_per_play @float_property_decorator def pass_first_downs(self): """ Returns a ``float`` of the average number of first downs from passing plays per game. """ return self._pass_first_downs @float_property_decorator def opponents_pass_first_downs(self): """ Returns a ``float`` of the opponents' average number of first downs from passing plays per game. """ return self._opponents_pass_first_downs @float_property_decorator def rush_first_downs(self): """ Returns a ``float`` of the average number of first downs from rushing plays per game. """ return self._rush_first_downs @float_property_decorator def opponents_rush_first_downs(self): """ Returns a ``float`` of the opponents' average number of first downs from rushing plays per game. """ return self._opponents_rush_first_downs @float_property_decorator def first_downs_from_penalties(self): """ Returns a ``float`` of the average number of first downs from an opponent's penalties per game. """ return self._first_downs_from_penalties @float_property_decorator def opponents_first_downs_from_penalties(self): """ Returns a ``float`` of the opponents' average number of first downs from an opponent's penalties per game. """ return self._opponents_first_downs_from_penalties @float_property_decorator def first_downs(self): """ Returns a ``float`` of the total number of first downs achieved per game. """ return self._first_downs @float_property_decorator def opponents_first_downs(self): """ Returns a ``float`` of the opponents' total number of first downs achieved per game. """ return self._opponents_first_downs @float_property_decorator def penalties(self): """ Returns a ``float`` of the average number of penalties conceded per game. """ return self._penalties @float_property_decorator def opponents_penalties(self): """ Returns a ``float`` of the opponents' average number of penalties conceded per game. """ return self._opponents_penalties @float_property_decorator def yards_from_penalties(self): """ Returns a ``float`` of the average number of yards gained from an opponent's penalties per game. """ return self._yards_from_penalties @float_property_decorator def opponents_yards_from_penalties(self): """ Returns a ``float`` of the opponents' average number of yards gained from an opponent's penalties per game. """ return self._opponents_yards_from_penalties
[docs]class Teams: """ A list of all NCAA Men's Football teams and their stats in a given year. Finds and retrieves a list of all NCAA Men's Football teams from www.sports-reference.com and creates a Team instance for every team that participated in the league in a given year. The Team class comprises a list of all major stats and a few identifiers for the requested season. Parameters ---------- year : string (optional) The requested year to pull stats from. season_page : string (optional) Optionally specify the filename of a local file to use to pull data instead of downloading from sports-reference.com. This file should be of the Season page for the designated year. offensive_stats : string (optional) Optionally specify the filename of a local file to use to pull data instead of downloading from sports-reference.com. This file should be of the Offensive Stats page for the designated year. defensive_stats : string (optional) Optionally specify the filename of a local file to use to pull data instead of downloading from sports-reference.com. This file should be of the Defensive Stats page for the designated year. """ def __init__(self, year=None, season_page=None, offensive_stats=None, defensive_stats=None): self._teams = [] self._conferences_dict = Conferences(year, True).team_conference team_data_dict, year = _retrieve_all_teams(year, season_page, offensive_stats, defensive_stats) self._instantiate_teams(team_data_dict, year) def __getitem__(self, abbreviation): """ Return a specified team. Returns a team's instance in the Teams class as specified by the team's short name. Parameters ---------- abbreviation : string An NCAAF team's short name (ie. 'PURDUE' for the Purdue Boilermakers). Returns ------- Team instance If the requested team can be found, its Team instance is returned. Raises ------ ValueError If the requested team is not present within the Teams list. """ for team in self._teams: if team.abbreviation.upper() == abbreviation.upper(): return team raise ValueError('Team abbreviation %s not found' % abbreviation) def __call__(self, abbreviation): """ Return a specified team. Returns a team's instance in the Teams class as specified by the team's abbreviation. This method is a wrapper for __getitem__. Parameters ---------- abbreviation : string An NCAAF team's short name (ie. 'PURDUE' for the Purdue Boilermakers). Returns ------- Team instance If the requested team can be found, its Team instance is returned. """ return self.__getitem__(abbreviation) def __str__(self): """ Return the string representation of the class. """ teams = [f'{team.name} ({team.abbreviation})'.strip() for team in self._teams] return '\n'.join(teams) def __repr__(self): """ Return the string representation of the class. """ return self.__str__() def __iter__(self): """Returns an iterator of all of the NCAAF teams for a given season.""" return iter(self._teams) def __len__(self): """Returns the number of NCAAF teams for a given season.""" return len(self._teams) def _instantiate_teams(self, team_data_dict, year): """ Create a Team instance for all teams. Once all team information has been pulled from the various webpages, create a Team instance for each team and append it to a larger list of team instances for later use. Parameters ---------- team_data_dict : dictionary A ``dictionary`` containing all stats information in HTML format as well as team rankings, indexed by team abbreviation. year : string A ``string`` of the requested year to pull stats from. """ if not team_data_dict: return for team_name, team_data in team_data_dict.items(): if team_name.lower() not in self._conferences_dict: conference = None else: conference = self._conferences_dict[team_name.lower()] team = Team(team_data=team_data['data'], team_conference=conference, year=year) self._teams.append(team) @property def dataframes(self): """ Returns a pandas DataFrame where each row is a representation of the Team class. Rows are indexed by the team abbreviation. """ frames = [] for team in self.__iter__(): frames.append(team.dataframe) return pd.concat(frames)