Source code for sportsreference.mlb.teams

import pandas as pd
import re
from .constants import (ELEMENT_INDEX,
                        PARSING_SCHEME,
                        STANDINGS_URL,
                        TEAM_ELEMENT,
                        TEAM_STATS_URL)
from functools import wraps
from pyquery import PyQuery as pq
from .. import utils
from ..decorators import float_property_decorator, int_property_decorator
from .roster import Roster
from .schedule import Schedule


[docs]def mlb_int_property_decorator(func): @property @wraps(func) def wrapper(*args): value = func(*args) # Equivalent to the calling property's method name field = func.__name__ try: record = value.split('-') except AttributeError: return None try: return int(record[TEAM_ELEMENT[field]]) except (TypeError, ValueError, IndexError): return None return wrapper
[docs]class Team: """ An object containing all of a team's season information. Finds and parses all team stat information and identifiers, such as rank, name, and abbreviation, and sets them as properties which can be directly read from for easy reference. 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. rank : int A team's position in the league based on the number of points they obtained during the season. year : string (optional) The requested year to pull stats from. """ def __init__(self, team_data, rank, year=None): self._year = year self._rank = rank self._abbreviation = None self._name = None self._league = None self._games = None self._wins = None self._losses = None self._win_percentage = None self._streak = None self._runs = None self._runs_against = None self._run_difference = None self._strength_of_schedule = None self._simple_rating_system = None self._pythagorean_win_loss = None self._luck = None self._interleague_record = None self._home_record = None self._away_record = None self._extra_inning_record = None self._single_run_record = None self._record_vs_right_handed_pitchers = None self._record_vs_left_handed_pitchers = None self._record_vs_teams_over_500 = None self._record_vs_teams_under_500 = None self._last_ten_games_record = None self._last_twenty_games_record = None self._last_thirty_games_record = None self._number_players_used = None self._average_batter_age = None self._plate_appearances = None self._at_bats = None self._total_runs = None self._hits = None self._doubles = None self._triples = None self._home_runs = None self._runs_batted_in = None self._stolen_bases = None self._times_caught_stealing = None self._bases_on_balls = None self._times_struck_out = None self._batting_average = None self._on_base_percentage = None self._slugging_percentage = None self._on_base_plus_slugging_percentage = None self._on_base_plus_slugging_percentage_plus = None self._total_bases = None self._grounded_into_double_plays = None self._times_hit_by_pitch = None self._sacrifice_hits = None self._sacrifice_flies = None self._intentional_bases_on_balls = None self._runners_left_on_base = None self._number_of_pitchers = None self._average_pitcher_age = None self._runs_allowed_per_game = None self._earned_runs_against = None self._games_finished = None self._complete_games = None self._shutouts = None self._complete_game_shutouts = None self._saves = None self._innings_pitched = None self._hits_allowed = None self._home_runs_against = None self._bases_on_walks_given = None self._strikeouts = None self._hit_pitcher = None self._balks = None self._wild_pitches = None self._batters_faced = None self._earned_runs_against_plus = None self._fielding_independent_pitching = None self._whip = None self._hits_per_nine_innings = None self._home_runs_per_nine_innings = None self._bases_on_walks_given_per_nine_innings = None self._strikeouts_per_nine_innings = None self._strikeouts_per_base_on_balls = None self._opposing_runners_left_on_base = None self._parse_team_data(team_data) def _parse_name(self, team_data): """ Parses the team's name. On the pages being parsed, the team's name doesn't follow the standard parsing algorithm that we use for the fields, and requires a special one-off algorithm. The name is attached in the 'title' attribute from within 'team_ID'. A few simple regex subs captures the team name. The '_name' attribute is applied with the captured team name from this function. 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. """ name = team_data('td[data-stat="team_ID"]:first') name = re.sub(r'.*title="', '', str(name)) name = re.sub(r'".*', '', name) setattr(self, '_name', name) def _parse_team_data(self, team_data): """ Parses a value for every attribute. This function looks through every attribute with the exception of '_rank' 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__: # The short field truncates the leading '_' in the attribute name. short_field = str(field)[1:] # The rank attribute is passed directly to the class during # instantiation. if field == '_rank' or \ field == '_year': continue elif field == '_name': self._parse_name(team_data) continue # Default to returning the first element returned unless a # subsequent element is desired. For example, total runs and # runs per game are two different fields, but they both share # the same attribute of 'R' in the HTML tables. index = 0 if short_field in ELEMENT_INDEX.keys(): index = ELEMENT_INDEX[short_field] value = utils._parse_field(PARSING_SCHEME, team_data, short_field, index) 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 'HOU'. """ fields_to_include = { 'abbreviation': self.abbreviation, 'at_bats': self.at_bats, 'average_batter_age': self.average_batter_age, 'average_pitcher_age': self.average_pitcher_age, 'away_losses': self.away_losses, 'away_record': self.away_record, 'away_wins': self.away_wins, 'balks': self.balks, 'bases_on_balls': self.bases_on_balls, 'bases_on_walks_given': self.bases_on_walks_given, 'bases_on_walks_given_per_nine_innings': self.bases_on_walks_given_per_nine_innings, 'batters_faced': self.batters_faced, 'batting_average': self.batting_average, 'complete_game_shutouts': self.complete_game_shutouts, 'complete_games': self.complete_games, 'doubles': self.doubles, 'earned_runs_against': self.earned_runs_against, 'earned_runs_against_plus': self.earned_runs_against_plus, 'extra_inning_losses': self.extra_inning_losses, 'extra_inning_record': self.extra_inning_record, 'extra_inning_wins': self.extra_inning_wins, 'fielding_independent_pitching': self.fielding_independent_pitching, 'games': self.games, 'games_finished': self.games_finished, 'grounded_into_double_plays': self.grounded_into_double_plays, 'hit_pitcher': self.hit_pitcher, 'hits': self.hits, 'hits_allowed': self.hits_allowed, 'hits_per_nine_innings': self.hits_per_nine_innings, 'home_losses': self.home_losses, 'home_record': self.home_record, 'home_runs': self.home_runs, 'home_runs_against': self.home_runs_against, 'home_runs_per_nine_innings': self.home_runs_per_nine_innings, 'home_wins': self.home_wins, 'innings_pitched': self.innings_pitched, 'intentional_bases_on_balls': self.intentional_bases_on_balls, 'interleague_record': self.interleague_record, 'last_ten_games_record': self.last_ten_games_record, 'last_thirty_games_record': self.last_thirty_games_record, 'last_twenty_games_record': self.last_twenty_games_record, 'league': self.league, 'losses': self.losses, 'losses_last_ten_games': self.losses_last_ten_games, 'losses_last_thirty_games': self.losses_last_thirty_games, 'losses_last_twenty_games': self.losses_last_twenty_games, 'losses_vs_left_handed_pitchers': self.losses_vs_left_handed_pitchers, 'losses_vs_right_handed_pitchers': self.losses_vs_right_handed_pitchers, 'losses_vs_teams_over_500': self.losses_vs_teams_over_500, 'losses_vs_teams_under_500': self.losses_vs_teams_under_500, 'luck': self.luck, 'name': self.name, 'number_of_pitchers': self.number_of_pitchers, 'number_players_used': self.number_players_used, 'on_base_percentage': self.on_base_percentage, 'on_base_plus_slugging_percentage': self.on_base_plus_slugging_percentage, 'on_base_plus_slugging_percentage_plus': self.on_base_plus_slugging_percentage_plus, 'opposing_runners_left_on_base': self.opposing_runners_left_on_base, 'plate_appearances': self.plate_appearances, 'pythagorean_win_loss': self.pythagorean_win_loss, 'rank': self.rank, 'record_vs_left_handed_pitchers': self.record_vs_left_handed_pitchers, 'record_vs_right_handed_pitchers': self.record_vs_right_handed_pitchers, 'record_vs_teams_over_500': self.record_vs_teams_over_500, 'record_vs_teams_under_500': self.record_vs_teams_under_500, 'run_difference': self.run_difference, 'runners_left_on_base': self.runners_left_on_base, 'runs': self.runs, 'runs_against': self.runs_against, 'runs_allowed_per_game': self.runs_allowed_per_game, 'runs_batted_in': self.runs_batted_in, 'sacrifice_flies': self.sacrifice_flies, 'sacrifice_hits': self.sacrifice_hits, 'saves': self.saves, 'shutouts': self.shutouts, 'simple_rating_system': self.simple_rating_system, 'single_run_losses': self.single_run_losses, 'single_run_record': self.single_run_record, 'single_run_wins': self.single_run_wins, 'slugging_percentage': self.slugging_percentage, 'stolen_bases': self.stolen_bases, 'streak': self.streak, 'strength_of_schedule': self.strength_of_schedule, 'strikeouts': self.strikeouts, 'strikeouts_per_base_on_balls': self.strikeouts_per_base_on_balls, 'strikeouts_per_nine_innings': self.strikeouts_per_nine_innings, 'times_caught_stealing': self.times_caught_stealing, 'times_hit_by_pitch': self.times_hit_by_pitch, 'times_struck_out': self.times_struck_out, 'total_bases': self.total_bases, 'total_runs': self.total_runs, 'triples': self.triples, 'whip': self.whip, 'wild_pitches': self.wild_pitches, 'win_percentage': self.win_percentage, 'wins': self.wins, 'wins_last_ten_games': self.wins_last_ten_games, 'wins_last_thirty_games': self.wins_last_thirty_games, 'wins_last_twenty_games': self.wins_last_twenty_games, 'wins_vs_left_handed_pitchers': self.wins_vs_left_handed_pitchers, 'wins_vs_right_handed_pitchers': self.wins_vs_right_handed_pitchers, 'wins_vs_teams_over_500': self.wins_vs_teams_over_500, 'wins_vs_teams_under_500': self.wins_vs_teams_under_500 } return pd.DataFrame([fields_to_include], index=[self._abbreviation]) @int_property_decorator def rank(self): """ Returns an ``int`` of the team's rank based on their win percentage. """ return self._rank @property def abbreviation(self): """ Returns a ``string`` of the team's abbreviation, such as 'HOU' for the Houston Astros. """ 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 'Houston Astros'. """ return self._name @property def league(self): """ Returns a ``string`` of the two letter abbreviation of the league, such as 'AL' for the American League. """ return self._league @int_property_decorator def games(self): """ Returns an ``int`` of the 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 number of wins divided by the number of games played during the season. Percentage ranges from 0-1. """ return self._win_percentage @property def streak(self): """ Returns a ``string`` of the team's current winning or losing streak, such as 'W 3' for a team on a 3-game winning streak. """ return self._streak @float_property_decorator def runs(self): """ Returns a ``float`` of the average number of runs scored per game by the team. """ return self._runs @float_property_decorator def runs_against(self): """ Returns a ``float`` of the average number of runs scored per game by the opponent. """ return self._runs_against @float_property_decorator def run_difference(self): """ Returns a ``float`` of the difference between the number of runs scored and the number of runs given up per game. Positive numbers indicate the team scores more per game than they are scored on. """ return self._run_difference @float_property_decorator def strength_of_schedule(self): """ Returns a ``float`` denoting a team's strength of schedule, based on runs scores and conceded. Higher values result in more challenging schedules while 0.0 is an average schedule. """ return self._strength_of_schedule @float_property_decorator def simple_rating_system(self): """ Returns a ``float`` of the average number of runs per game a team scores compared to average. """ return self._simple_rating_system @property def pythagorean_win_loss(self): """ Returns a ``string`` of the team's expected win-loss record based on the runs scored and allowed. Record is in the format 'W-L'. """ return self._pythagorean_win_loss @int_property_decorator def luck(self): """ Returns an ``int`` of the difference between the current wins and losses compared to the pythagorean wins and losses. """ return self._luck @property def interleague_record(self): """ Returns a ``string`` of the team's interleague record. Record is in the format 'W-L'. """ return self._interleague_record @property def home_record(self): """ Returns a ``string`` of the team's home record. Record is in the format 'W-L'. """ return self._home_record @mlb_int_property_decorator def home_wins(self): """ Returns an ``int`` of the number of wins at home during the season. """ return self._home_record @mlb_int_property_decorator def home_losses(self): """ Returns an ``int`` of the number of losses at home during the season. """ return self._home_record @property def away_record(self): """ Returns a ``string`` of the team's away record. Record is in the format 'W-L'. """ return self._away_record @mlb_int_property_decorator def away_wins(self): """ Returns an ``int`` of the number of away wins during the season. """ return self._away_record @mlb_int_property_decorator def away_losses(self): """ Returns an ``int`` of the number of away losses during the season. """ return self._away_record @property def extra_inning_record(self): """ Returns a ``string`` of the team's record when the game has gone to extra innings. Record is in the format 'W-L'. """ return self._extra_inning_record @mlb_int_property_decorator def extra_inning_wins(self): """ Returns an ``int`` of the number of wins the team has when the game has gone to extra innings. """ return self._extra_inning_record @mlb_int_property_decorator def extra_inning_losses(self): """ Returns an ``int`` of the number of losses the team has when the game has gone to extra innings. """ return self._extra_inning_record @property def single_run_record(self): """ Returns a ``string`` of the team's record when only one run is scored. Record is in the format 'W-L'. """ return self._single_run_record @mlb_int_property_decorator def single_run_wins(self): """ Returns an ``int`` of the number of wins the team has when only one run is scored. """ return self._single_run_record @mlb_int_property_decorator def single_run_losses(self): """ Returns an ``int`` of the number of losses the team has when only one run is scored. """ return self._single_run_record @property def record_vs_right_handed_pitchers(self): """ Returns a ``string`` of the team's record against right-handed pitchers. Record is in the format 'W-L'. """ return self._record_vs_right_handed_pitchers @mlb_int_property_decorator def wins_vs_right_handed_pitchers(self): """ Returns an ``int`` of the number of wins against right-handed pitchers. """ return self._record_vs_right_handed_pitchers @mlb_int_property_decorator def losses_vs_right_handed_pitchers(self): """ Returns an ``int`` of the number of losses against right-handed pitchers. """ return self._record_vs_right_handed_pitchers @property def record_vs_left_handed_pitchers(self): """ Returns a ``string`` of the team's record against left-handed pitchers. Record is in the format 'W-L'. """ return self._record_vs_left_handed_pitchers @mlb_int_property_decorator def wins_vs_left_handed_pitchers(self): """ Returns an ``int`` of number of wins against left-handed pitchers. """ return self._record_vs_left_handed_pitchers @mlb_int_property_decorator def losses_vs_left_handed_pitchers(self): """ Returns an ``int`` of number of losses against left-handed pitchers. """ return self._record_vs_left_handed_pitchers @property def record_vs_teams_over_500(self): """ Returns a ``string`` of the team's record against teams with a win percentage over 500. Record is in the format 'W-L'. """ return self._record_vs_teams_over_500 @mlb_int_property_decorator def wins_vs_teams_over_500(self): """ Returns an ``int`` of the number of wins against teams over 500. """ return self._record_vs_teams_over_500 @mlb_int_property_decorator def losses_vs_teams_over_500(self): """ Returns an ``int`` of the number of losses against teams over 500. """ return self._record_vs_teams_over_500 @property def record_vs_teams_under_500(self): """ Returns a ``string`` of the team's record against teams with a win percentage under 500. Record is in the format 'W-L'. """ return self._record_vs_teams_under_500 @mlb_int_property_decorator def wins_vs_teams_under_500(self): """ Returns an ``int`` of the number of wins against teams under 500. """ return self._record_vs_teams_under_500 @mlb_int_property_decorator def losses_vs_teams_under_500(self): """ Returns an ``int`` of the number of losses against teams under 500. """ return self._record_vs_teams_under_500 @property def last_ten_games_record(self): """ Returns a ``string`` of the team's record over the last ten games. Record is in the format 'W-L'. """ return self._last_ten_games_record @mlb_int_property_decorator def wins_last_ten_games(self): """ Returns an ``int`` of the number of wins in the last 10 games. """ return self._last_ten_games_record @mlb_int_property_decorator def losses_last_ten_games(self): """ Returns an ``int`` of the number of losses in the last 10 games. """ return self._last_ten_games_record @property def last_twenty_games_record(self): """ Returns a ``string`` of the team's record over the last twenty games. Record is in the format 'W-L'. """ return self._last_twenty_games_record @mlb_int_property_decorator def wins_last_twenty_games(self): """ Returns an ``int`` of the number of wins in the last 20 games. """ return self._last_twenty_games_record @mlb_int_property_decorator def losses_last_twenty_games(self): """ Returns an ``int`` of the number of losses in the last 20 games. """ return self._last_twenty_games_record @property def last_thirty_games_record(self): """ Returns a ``string`` of the team's record over the last thirty games. Record is in the format 'W-L'. """ return self._last_thirty_games_record @mlb_int_property_decorator def wins_last_thirty_games(self): """ Returns an ``int`` of the number of wins in the last 30 games. """ return self._last_thirty_games_record @mlb_int_property_decorator def losses_last_thirty_games(self): """ Returns an ``int`` of the number of losses in the last 30 games. """ return self._last_thirty_games_record @int_property_decorator def number_players_used(self): """ Returns an ``int`` of the number of different players used during the season. """ return self._number_players_used @float_property_decorator def average_batter_age(self): """ Returns a ``float`` of the average batter age weighted by their number of at bats plus the number of games participated in. """ return self._average_batter_age @int_property_decorator def plate_appearances(self): """ Returns an ``int`` of the total number of plate appearances for the team. """ return self._plate_appearances @int_property_decorator def at_bats(self): """ Returns an ``int`` of the total number of at bats for the team. """ return self._at_bats @int_property_decorator def total_runs(self): """ Returns an ``int`` of the total number of runs scored during the season. """ return self._total_runs @int_property_decorator def hits(self): """ Returns an ``int`` of the total number of hits during the season. """ return self._hits @int_property_decorator def doubles(self): """ Returns an ``int`` of the total number of doubles hit by the team. """ return self._doubles @int_property_decorator def triples(self): """ Returns an ``int`` of the total number of tripes hit by the team. """ return self._triples @int_property_decorator def home_runs(self): """ Returns an ``int`` of the total number of home runs hit by the team. """ return self._home_runs @int_property_decorator def runs_batted_in(self): """ Returns an ``int`` of the total number of runs batted in by the team. """ return self._runs_batted_in @int_property_decorator def stolen_bases(self): """ Returns an ``int`` of the total number of bases stolen by the team. """ return self._stolen_bases @int_property_decorator def times_caught_stealing(self): """ Returns an ``int`` of the number of times a player was caught stealing. """ return self._times_caught_stealing @int_property_decorator def bases_on_balls(self): """ Returns an ``int`` of the number of bases on walks. """ return self._bases_on_balls @int_property_decorator def times_struck_out(self): """ Returns an ``int`` of the total number of times the team struck out. """ return self._times_struck_out @float_property_decorator def batting_average(self): """ Returns a ``float`` of the batting average for the team. Percentage ranges from 0-1. """ return self._batting_average @float_property_decorator def on_base_percentage(self): """ Returns a ``float`` of the percentage of at bats that result in a player taking a base. Percentage ranges from 0-1. """ return self._on_base_percentage @float_property_decorator def slugging_percentage(self): """ Returns a ``float`` of the ratio of total bases gained per at bat. """ return self._slugging_percentage @float_property_decorator def on_base_plus_slugging_percentage(self): """ Returns a ``float`` of the sum of the on base percentage plus the slugging percentage. """ return self._on_base_plus_slugging_percentage @int_property_decorator def on_base_plus_slugging_percentage_plus(self): """ Returns an ``int`` of the on base percentage plus the slugging percentage, adjusted to the team's home ballpark. """ return self._on_base_plus_slugging_percentage_plus @int_property_decorator def total_bases(self): """ Returns an ``int`` of the total number of bases a team has gained during the season. """ return self._total_bases @int_property_decorator def grounded_into_double_plays(self): """ Returns an ``int`` of the total number double plays grounded into by the team. """ return self._grounded_into_double_plays @int_property_decorator def times_hit_by_pitch(self): """ Returns an ``int`` of the total number of times a batter was hit by an opponent's pitch. """ return self._times_hit_by_pitch @int_property_decorator def sacrifice_hits(self): """ Returns an ``int`` of the total number of sacrifice hits the team made during the season. """ return self._sacrifice_hits @int_property_decorator def sacrifice_flies(self): """ Returns an ``int`` of the total number of sacrifice flies the team made during the season. """ return self._sacrifice_flies @int_property_decorator def intentional_bases_on_balls(self): """ Returns an ``int`` of the total number of times a player took a base from an intentional walk. """ return self._intentional_bases_on_balls @int_property_decorator def runners_left_on_base(self): """ Returns an ``int`` of the total number of runners left on base at the end of an inning. """ return self._runners_left_on_base @int_property_decorator def number_of_pitchers(self): """ Returns an ``int`` of the total number of pitchers used during a season. """ return self._number_of_pitchers @float_property_decorator def average_pitcher_age(self): """ Returns a ``float`` of the average pitcher age weighted by the number of games started, followed by the number of games played and saves. """ return self._average_pitcher_age @float_property_decorator def runs_allowed_per_game(self): """ Returns a ``float`` of the average number of runs a team has allowed per game. """ return self._runs_allowed_per_game @float_property_decorator def earned_runs_against(self): """ Returns a ``float`` of the average number of earned runs against for a team. """ return self._earned_runs_against @int_property_decorator def games_finished(self): """ Returns an ``int`` of the number of games finished which is equivalent to the number of games played minus the number of complete games during the season. """ return self._games_finished @int_property_decorator def complete_games(self): """ Returns an ``int`` of the total number of complete games a team has accumulated during the season. """ return self._complete_games @int_property_decorator def shutouts(self): """ Returns an ``int`` of the total number of shutouts a team has accumulated during the season. """ return self._shutouts @int_property_decorator def complete_game_shutouts(self): """ Returns an ``int`` of the total number of complete games where the opponent scored zero runs. """ return self._complete_game_shutouts @int_property_decorator def saves(self): """ Returns an ``int`` of the total number of saves a team has accumulated during the season. """ return self._saves @float_property_decorator def innings_pitched(self): """ Returns a ``float`` of the total number of innings pitched by a team during the season. """ return self._innings_pitched @int_property_decorator def hits_allowed(self): """ Returns an ``int`` of the total number of hits allowed during the season. """ return self._hits_allowed @int_property_decorator def home_runs_against(self): """ Returns an ``int`` of the total number of home runs given up during the season. """ return self._home_runs_against @int_property_decorator def bases_on_walks_given(self): """ Returns an ``int`` of the total number of bases from walks given up by a team during the season. """ return self._bases_on_walks_given @int_property_decorator def strikeouts(self): """ Returns an ``int`` of the total number of times a team has struck out an opponent. """ return self._strikeouts @int_property_decorator def hit_pitcher(self): """ Returns an ``int`` of the total number of times a pitcher has hit an opposing batter. """ return self._hit_pitcher @int_property_decorator def balks(self): """ Returns an ``int`` of the total number of times a pitcher has balked. """ return self._balks @int_property_decorator def wild_pitches(self): """ Returns an ``int`` of the total number of wild pitches thrown by a team during a season. """ return self._wild_pitches @int_property_decorator def batters_faced(self): """ Returns an ``int`` of the total number of batters all pitchers have faced during a season. """ return self._batters_faced @int_property_decorator def earned_runs_against_plus(self): """ Returns an ``int`` of the team's average earned runs against, adjusted for the home ballpark. """ return self._earned_runs_against_plus @float_property_decorator def fielding_independent_pitching(self): """ Returns a ``float`` of the team's effectiveness at preventing home runs, walks, batters being hit by pitches, and strikeouts. """ return self._fielding_independent_pitching @float_property_decorator def whip(self): """ Returns a ``float`` of the average number of walks plus hits by the opponent per inning. """ return self._whip @float_property_decorator def hits_per_nine_innings(self): """ Returns a ``float`` of the average number of hits per nine innings by the opponent. """ return self._hits_per_nine_innings @float_property_decorator def home_runs_per_nine_innings(self): """ Returns a ``float`` of the average number of home runs per nine innings by the opponent. """ return self._home_runs_per_nine_innings @float_property_decorator def bases_on_walks_given_per_nine_innings(self): """ Returns a ``float`` of the average number of walks conceded per nine innings. """ return self._bases_on_walks_given_per_nine_innings @float_property_decorator def strikeouts_per_nine_innings(self): """ Returns a ``float`` of the average number of strikeouts a team throws per nine innings. """ return self._strikeouts_per_nine_innings @float_property_decorator def strikeouts_per_base_on_balls(self): """ Returns a ``float`` of the average number of strikeouts per walk thrown by a team. """ return self._strikeouts_per_base_on_balls @int_property_decorator def opposing_runners_left_on_base(self): """ Returns an ``int`` of the total number of opponents a team has left on bases at the end of an inning. """ return self._opposing_runners_left_on_base
[docs]class Teams: """ A list of all MLB teams and their stats in a given year. Finds and retrieves a list of all MLB teams from www.baseball-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. """ def __init__(self, year=None): self._teams = [] self._retrieve_all_teams(year) def __getitem__(self, abbreviation): """ Return a specified team. Returns a team's instance in the Teams class as specified by the team's abbreviation. Parameters ---------- abbreviation : string An MLB team's three letter abbreviation (ie. 'HOU' for Houston Astros). 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 MLB team's three letter abbreviation (ie. 'HOU' for Houson Astros). Returns ------- Team instance If the requested team can be found, its Team instance is returned. """ return self.__getitem__(abbreviation) def __repr__(self): """Returns a ``list`` of all MLB teams for the given season.""" return self._teams def __iter__(self): """Returns an iterator of all of the MLB teams for a given season.""" return iter(self.__repr__()) def __len__(self): """Returns the number of MLB teams for a given season.""" return len(self.__repr__()) def _add_stats_data(self, teams_list, team_data_dict): """ Add a team's stats row to a dictionary. Pass table contents and a stats dictionary of all teams to accumulate all stats for each team in a single variable. Parameters ---------- teams_list : generator A generator of all row items in a given table. team_data_dict : {str: {'data': str, 'rank': int}} dictionary A dictionary where every key is the team's abbreviation and every value is another dictionary with a 'data' key which contains the string version of the row data for the matched team, and a 'rank' key which is the rank of the team. Returns ------- dictionary An updated version of the team_data_dict with the passed table row information included. """ # Teams are listed in terms of rank with the first team being #1 rank = 1 for team_data in teams_list: # Skip the league average row if 'class="league_average_table"' in str(team_data): continue abbr = utils._parse_field(PARSING_SCHEME, team_data, 'abbreviation') try: team_data_dict[abbr]['data'] += team_data except KeyError: team_data_dict[abbr] = {'data': team_data, 'rank': rank} rank += 1 return team_data_dict def _retrieve_all_teams(self, year): """ Find and create Team instances for all teams in the given season. For a given season, parses the specified MLB stats table and finds all requested stats. Each team then has a Team instance created which includes all requested stats and a few identifiers, such as the team's name and abbreviation. All of the individual Team instances are added to a list. Note that this method is called directly once Teams is invoked and does not need to be called manually. Parameters ---------- year : string The requested year to pull stats from. """ team_data_dict = {} if not year: year = utils._find_year_for_season('mlb') # If stats for the requested season do not exist yet (as is the # case right before a new season begins), attempt to pull the # previous year's stats. If it exists, use the previous year # instead. if not utils._url_exists(STANDINGS_URL % year) and \ utils._url_exists(STANDINGS_URL % str(int(year) - 1)): year = str(int(year) - 1) doc = pq(STANDINGS_URL % year) div_prefix = 'div#all_expanded_standings_overall' standings = utils._get_stats_table(doc, div_prefix) doc = pq(TEAM_STATS_URL % year) div_prefix = 'div#all_teams_standard_%s' batting_stats = utils._get_stats_table(doc, div_prefix % 'batting') pitching_stats = utils._get_stats_table(doc, div_prefix % 'pitching') if not standings and not batting_stats and not pitching_stats: utils._no_data_found() return for stats_list in [standings, batting_stats, pitching_stats]: team_data_dict = self._add_stats_data(stats_list, team_data_dict) for team_data in team_data_dict.values(): team = Team(team_data['data'], team_data['rank'], 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)