Best Python code snippet using fMBT_python
touchdown.py
Source:touchdown.py  
1# -*- coding: utf-8 -*-2"""3Created on Thu Mar 10 21:28:51 20164@author: Tobias Jachowski5"""6import matplotlib.pyplot as plt7import numpy as np8from matplotlib.widgets import Cursor9from scipy.optimize import fsolve10from pyoti.modification.modification import Modification, GraphicalMod11from pyoti import traces as tc12class ITouchdown(GraphicalMod):13    """14    Subclass of Touchdown that provides graphical interfaces to adjust the fit15    parameters.16    """17    def __init__(self, **kwargs):18        super().__init__(**kwargs)19        # Define attributes needed for the graphical fitting of the touchdown20        # a cursor on the axes to show upper fitting border and left/right21        # (middle) border22        self._cursor = None23        self._lines = {}24        self._ax = None25        self.supertitle = None26    def _figure(self):27        """28        Initialize and show an interactive plot for fitting the touchdown.29        Adjust the fit parameters interactively by displaying the fitted30        touchdown. The plot of the fitting is stored in self.figure.31        """32        # create new figure and axes for fitting the touchdown33        figure, ax = plt.subplots(1, 1, sharex=True, sharey=True)34        self._ax = ax35        # create lines to plot the data for the fit and for displaying fitting36        # result37        self._lines['orig_data'] = ax.plot([0], [0], tc.color('psdZ'))[0]38        self._lines['binned_data'] = ax.plot([0], [0], 'b.')[0]39        # cursor to display the "boundaries" for fitdata40        self._cursor = Cursor(ax, useblit=True, color='red', lw=1)41        # initialize all lines for the plot that represent the fit paramters42        # extrapolation of fit left43        self._lines['ext_left'] = ax.plot([0, 0], [0, 0], 'c', lw=1)[0]44        # extrapolation of fit right45        self._lines['ext_right'] = ax.plot([0, 0], [0, 0], 'c', lw=1)[0]46        # fit left47        self._lines['fit_left'] = ax.plot([0, 0], [0, 0], 'r', lw=3)[0]48        # fit right49        self._lines['fit_right'] = ax.plot([0, 0], [0, 0], 'g', lw=3)[0]50        # touchdown position51        self._lines['touchdown'] = ax.axvline(x=0.0, color='y', lw=2)52        # touchdown of bead, where positionZ equal to 0.053        self._lines['touchdown_calib'] = ax.axvline(x=0.0, color='k', lw=2,54                                                    dashes=(10, 10))55        ax.set_xlabel(tc.label('positionZ'))56        ax.set_ylabel(tc.label('psdZ'))57        ax.ticklabel_format(useOffset=False)58        ax.grid(True)59        self.supertitle = figure.suptitle("Fit touchdown determination (move "60                                          "to upper and right/left limit, "61                                          "left/right click, repeat ...)")62        # method to update plot and perform the fit63        figure.canvas.mpl_connect('button_release_event',64                                  self._update_touchdown)65        return figure66    def _update_fig(self, data_changed=True, **kwargs):67        """68        Updates the interactive fitting plot: Set values of fit parameters,69        touchdown position and fitted lines70        """71        if data_changed:72            # data, [:,0] is positionZ, [:,1] is psdZ73            data = self.modification._get_data_based(74                traces=['positionZ', 'psdZ'], decimate=True, copy=False)75            self.modification.validate_fit_params(data=data)76            bin_means = self.modification.bin_means77            minx = data[:, 0].min() - 0.05e-6  # m78            maxx = data[:, 0].max() + 0.05e-6  # m79            miny = data[:, 1].min() - 0.0580            maxy = data[:, 1].max() + 0.0581            self._ax.set_xlim([minx * 1e6, maxx * 1e6])  # µm82            self._ax.set_ylim([miny, maxy])83            self._lines['orig_data'].set_data(data[:, 0] * 1e6, data[:, 1])84            self._lines['binned_data'].set_data(bin_means[:, 0] * 1e6,85                                                bin_means[:, 1])86        # get left and right datapoint means according to fit borders for87        # fitting88        bin_means = self.modification.bin_means89        left_means = self.modification.left_means90        right_means = self.modification.right_means91        self._lines['ext_left'].set_data(bin_means[:, 0] * 1e6,92                                         self.get_pv_left(bin_means[:, 0]))93        self._lines['ext_right'].set_data(bin_means[:, 0] * 1e6,94                                          self.get_pv_right(bin_means[:, 0]))95        self._lines['fit_left'].set_data(left_means[:, 0] * 1e6,96                                         self.get_pv_left(left_means[:, 0]))97        self._lines['fit_right'].set_data(right_means[:, 0] * 1e6,98                                          self.get_pv_right(right_means[:, 0]))99        self._lines['touchdown'].set_xdata([self.modification.touchdown * 1e6,100                                            self.modification.touchdown * 1e6])101        self._lines['touchdown_calib'].set_xdata(102            [self.modification._calibration.touchdown * 1e6,103             self.modification._calibration.touchdown * 1e6])104    def _pre_close_fig(self):105        # Store touchdown fit plot for documentation106        self.supertitle.set_text("Touchdown determined by polynomial fits")107        self._cursor.visible = False108        # update visibility status of self._cursor before removing reference109        # to it110        self._figure_canvas_draw()111        # Release unused memory112        self._cursor = None113        self._ax = None114        self._lines.clear()115        self.supertitle = None116    def _update_touchdown(self, event):117        """118        Gets called by events of the canvas object of the figure119        """120        self._set_fit_params(event)121        touchdown = self.modification.fit_touchdown()122        self.modification._set_touchdown_leave_auto(touchdown)123        self.update_fig(data_changed=False)124    def _set_fit_params(self, event):125        """126        Set the parameters for the fitting routine.127        """128        if event.button == 1:  # left mouse button -> adjust left fitdata129            # left border for fitdata130            self.modification.left = self._cursor.linev.get_xdata()[0] * 1e-6  # m131            # max value (psdZ) for fitdata132            self.modification.left_upper = self._cursor.lineh.get_ydata()[0]133        else:  # right (or middle) mouse button -> adjust right fitdata134            # right border for fitdata135            self.modification.right = self._cursor.linev.get_xdata()[0] * 1e-6  # m136            # max value (psdZ) for fitdata137            self.modification.right_upper = self._cursor.lineh.get_ydata()[0]138    def get_pv_left(self, x):139        return np.polyval(self.modification.pf_left, x)140    def get_pv_right(self, x):141        return np.polyval(self.modification.pf_right, x)142class Touchdown(Modification):143    """144    Determine the approximate touchdown145    The displacement sensitivity and stiffness of a calibration are always146    relative to and given absolute at the touchdown of the bead on the surface147    The positionZ is touchdown corrected by this modification.148    """149    GRAPHICALMOD = ITouchdown150    def __init__(self, fit_touchdown=True, **kwargs):151        traces_apply = ['positionZ']152        # the touchdown position determined by calibration and fitting153        super().__init__(automatic_switch=True, datapoints=2500,154                         traces_apply=traces_apply, **kwargs)155        # register a widget, giving a key, a function called upon change156        self.add_iattribute('touchdown', description="Touchdown (m)",157                            value=0.0)158        # Initially set touchdown to touchdown of calibration, if touchdown159        # should not be automatically fitted. This will automatically switch of160        # the automatic fitting.161        if not fit_touchdown:162            self.touchdown = self._calibration.touchdown163        # register a button to set the touchdown from calibration.touchdown164        self.add_iattribute('set_touchdown_calib',165                            description="Set touchdown from calibration",166                            callback_functions=[167                                self._set_touchdown_from_calibration,168                                self.evaluate])169        # Define attributes needed for the fitting of the touchdown170        self.left_upper = None  # max value (psdZ) for fitdata171        self.right_upper = None  # max value (psdZ) for fitdata172        self.left = None  # right/left border for fitdata173        self.right = None  # right/left border for fitdata174    def _recalculate(self):175        # calculate data for fitting176        self.validate_fit_params()177        # fit the touchdown178        touchdown = self.fit_touchdown()179        self._set_touchdown_leave_auto(touchdown)180    def _modify(self, data, samples, data_traces, data_index, mod_index):181        data[:, data_index] -= self.touchdown182        return data183    def validate_fit_params(self, data=None):184        # self.init_fit_parameters()185        if data is None:186            data = self._get_data_based(traces=['positionZ', 'psdZ'],187                                        decimate=True, copy=False)188        positionzmin = data[:, 0].min()189        positionzmax = data[:, 0].max()190        middle = positionzmin + (positionzmax - positionzmin) / 2191        upper = data[:, 1].max()192        # First initialisation of fit boundaries193        if self.left is None or self.right_upper is None:194            self.left_upper = upper   # max value (psdZ) for fitdata195            self.left = middle        # right/left border for fitdata196        if self.right is None or self.right_upper is None:197            self.right = middle       # right/left border for fitdata198            self.right_upper = upper  # max value (psdZ) for fitdata199        bin_means, bin_width = self.calculate_bin_means(data=data)200        self.bin_means = bin_means201        if not np.any(self.left_means_idx):202            # first, change only the upper boundary and leave the left one203            # usually solves problems, when psdZ was changed by an offset204            self.left_upper = upper205            if not np.any(self.left_means_idx):206                # still no means, change left boundary, too207                self.left = middle208        if not np.any(self.right_means_idx):209            # first, change only the upper boundary and leave the right one210            # usually solves problems, when psdZ was changed by an offset211            self.right_upper = upper212            if not np.any(self.right_means_idx):213                # still no means, change right boundary, too214                self.right = middle215    def fit_touchdown(self):216        """217        Performs the fit.218        In essence, it fits 2 polynomials of 2nd degree to the left (bead219        on surface) and to the right (free bead) portion of the psdZ data220        The intercept of these two polynomials determine the touchdown of the221        bead with the surface.222        """223        if self.left_means.shape[0] > 0 and self.right_means.shape[0] > 0:224            def f_left(x):225                return np.polyval(self.pf_left, x)226            def f_right(x):227                return np.polyval(self.pf_right, x)228            def findIntersection(fun0, fun1, x0):229                # one could also solve formula for the intersection230                # analytically, but fsolve is more flexible231                return fsolve(lambda x: fun0(x) - fun1(x), x0)232            middle = self.left + (self.right - self.left)/2233            touchdown = findIntersection(f_left, f_right, middle)[0]234            return touchdown235    def _set_touchdown_leave_auto(self, touchdown):236        self.iattributes.set_value('touchdown', touchdown,237                                   leave_automatic=True)238    def _set_touchdown_from_calibration(self):239        self.touchdown = self._calibration.touchdown240    @property241    def touchdown(self):242        return self.iattributes.touchdown243    @touchdown.setter244    def touchdown(self, touchdown):245        self.iattributes.touchdown = touchdown246    @property247    def _calibration(self):248        # calibration, which is used to:249        # - set touchdown from calibration250        # - visualize calibration.touchdown in GTouchdown251        return self.view_apply.calibration252    @property253    def pf_left(self):254        # get left datapoint means according to fit borders for fitting255        left_means = self.left_means256        # polynomial 2nd order order for negative positionZ257        return np.polyfit(left_means[:, 0], left_means[:, 1], 2)258    @property259    def pf_right(self):260        # get right datapoint means according to fit borders for fitting261        right_means = self.right_means262        # polynomial 2nd order for positive positionZ263        return np.polyfit(right_means[:, 0], right_means[:, 1], 2)264    @property265    def left_means(self):266        return self.bin_means[self.left_means_idx]267    @property268    def right_means(self):269        return self.bin_means[self.right_means_idx]270    @property271    def left_means_idx(self):272        x_check = self.bin_means[:, 0] < self.left273        y_check = self.bin_means[:, 1] < self.left_upper274        return np.logical_and(x_check, y_check)275    @property276    def right_means_idx(self):277        x_check = self.bin_means[:, 0] > self.right278        y_check = self.bin_means[:, 1] < self.right_upper279        return np.logical_and(x_check, y_check)280    @property281    def bin_means(self):282        if not hasattr(self, '_v_bin_means'):283            return None284        else:285            return self._v_bin_means286    @bin_means.setter287    def bin_means(self, bin_means):...td_regression_candidates.py
Source:td_regression_candidates.py  
1"""2Evaluates the TD regression candidates for a given position regarding3the mean. A high or low touchdown total is not predictive for future4performance as these players will often regress towards the mean or5average the following year.6"""7import os8import matplotlib.pyplot as plt9import numpy as np10import pandas as pd11import seaborn as sns12import tqdm13import src.preprocessing.playbyplay.playbyplay as pbp14from src.preprocessing.statistics.statistics import Statistics15sns.set_style("whitegrid")16def fix_player_names(name):17    split = name.split()18    first_initial = split[0][0]19    last_name = split[1]20    return '.'.join([first_initial, last_name])21if __name__ == "__main__":22    # year23    year = 202124    # position and play combinations25    comb = [("QB", "pass"), ("QB", "rush"), ("RB", "rush"), ("RB", "rec"), ("WR", "rec"), ("TE", "rec")]26    for position, play in comb:27        # load historical play-by-play data28        if not os.path.exists(f"../preprocessed/play-by-play/pbp_1999to{year}.csv"):29            df_prob = pbp.concat_playbyplay_data((1999, year))30            df_prob = df_prob.loc[:, ["rush_attempt", "rush_touchdown", "pass_attempt", "pass_touchdown",31                                      "yardline_100", "two_point_attempt", "year"]]32        else:33            df_prob = pd.DataFrame()34            chunks = pd.read_csv(f"../preprocessed/play-by-play/pbp_1999to{year}.csv", iterator=True, low_memory=False,35                                 chunksize=10000)36            for chunk in tqdm.tqdm(chunks):37                chunk = chunk.loc[:, ["rush_attempt", "rush_touchdown", "pass_attempt", "pass_touchdown",38                                      "yardline_100", "two_point_attempt", "year"]]39                df_prob = pd.concat([df_prob, chunk])40        # select data from previous years41        df_prob = df_prob.loc[(df_prob["year"] < year)]42        # select pass or run attempts43        if play == "pass" or play == "rec":44            # passing/receiving: pass attempt that ended in a touchdown45            df_prob = df_prob.loc[:, ["pass_attempt", "pass_touchdown", "yardline_100", "two_point_attempt"]]46            df_prob = df_prob.rename({"pass_attempt": "attempt", "pass_touchdown": "touchdown"}, axis=1)47        elif play == "rush":48            # rushing: rush attempt that ended in a touchdown49            df_prob = df_prob.loc[:, ["rush_attempt", "rush_touchdown", "yardline_100", "two_point_attempt"]]50            df_prob = df_prob.rename({"rush_attempt": "attempt", "rush_touchdown": "touchdown"}, axis=1)51        # select only normal attempts52        df_prob = df_prob.loc[(df_prob["two_point_attempt"] == 0) & (df_prob["attempt"] == 1)]53        # find probability of scoring a touchdown depending on distance to endzone54        df_prob = df_prob.groupby("yardline_100")["touchdown"].value_counts(normalize=True)55        df_prob = pd.DataFrame({"probability_of_touchdown": df_prob.values}, index=df_prob.index).reset_index()56        # keep stats where touchdown was scored and drop column57        df_prob = df_prob.loc[(df_prob["touchdown"] == 1)]58        df_prob = df_prob.drop("touchdown", axis=1)59        # plot probability of scoring a touchdown60        df_prob.plot(x="yardline_100", y="probability_of_touchdown", title=f"Probability for {play}ing TD")61        plt.savefig(f"../reports/td_regression_candidates/touchdown_probability_{play}.png")62        # load play-by-play data for defined year63        if not os.path.exists(f"../raw/play-by-play/play_by_play_{year}.csv"):64            df_train = pbp.get_playbyplay_data(year)65        else:66            df_train = pd.DataFrame()67            chunks = pd.read_csv(f"../raw/play-by-play/play_by_play_{year}.csv", iterator=True, low_memory=False,68                                 chunksize=10000, index_col=0)69            for chunk in tqdm.tqdm(chunks):70                df_train = pd.concat([df_train, chunk])71        # get player, team and distance to endzone72        if play == "pass":73            df_train = df_train.loc[:, ["passer_player_name", "posteam", "yardline_100"]]74        elif play == "rec":75            df_train = df_train.loc[:, ["receiver_player_name", "posteam", "yardline_100"]]76        elif play == "rush":77            df_train = df_train.loc[:, ["rusher_player_name", "posteam", "yardline_100"]]78        df_train = df_train.dropna()79        # rename features80        df_train = df_train.rename(columns={df_train.columns[0]: "player", "posteam": "team"})81        # join probability with training82        data = df_train.merge(df_prob, how="left", on="yardline_100")83        # group by player and team and sum up expected touchdowns84        data = data.groupby(["player", "team"], as_index=False).agg({"probability_of_touchdown": np.sum}).rename(85            {"probability_of_touchdown": "Expected touchdowns"}, axis=1)86        data = data.sort_values(by="Expected touchdowns", ascending=False)87        # rank the expected touchdowns88        data["Expected touchdowns rank"] = data["Expected touchdowns"].rank(ascending=False)89        # load final stats90        df_actual = Statistics(position, year).get_accumulated_data()91        # get player, team and td92        if play == "pass":93            df_actual = df_actual.loc[:, ["player", "team", "passing_td"]]94            df_actual = df_actual.rename({"passing_td": "touchdowns"}, axis=1)95        elif play == "rec":96            df_actual = df_actual.loc[:, ["player", "team", "receiving_td"]]97            df_actual = df_actual.rename({"receiving_td": "touchdowns"}, axis=1)98        elif play == "rush":99            df_actual = df_actual.loc[:, ["player", "team", "rushing_td"]]100            df_actual = df_actual.rename({"rushing_td": "touchdowns"}, axis=1)101        # clean up player names102        df_actual["player"] = df_actual["player"].apply(fix_player_names)103        # summarize the year104        df_actual = df_actual.groupby(["player", "team"]).agg({"touchdowns": np.sum}).reset_index()105        # merge raw and drop position106        data = df_actual.merge(data, how="left", on=["player", "team"]).dropna()107        # rename features and calculate rank of actual touchdowns108        data = data.rename({"touchdowns": "Actual touchdowns"}, axis=1)109        data["Actual touchdowns rank"] = data["Actual touchdowns"].rank(ascending=False)110        # calculate regression candidate111        data["Regression candidate"] = data["Expected touchdowns"] - data["Actual touchdowns"]112        data["Regression rank candidate"] = data["Actual touchdowns rank"] - data["Expected touchdowns rank"]113        # make simple true/false column for regression candidate114        data["Positive regression candidate"] = data["Regression candidate"] > 0115        # explore the statistics116        fig, ax = plt.subplots(figsize=(12, 8))117        ax.set_title(f"Positive regression candidates for {play} {position} in season {year}")118        # plot expected vs actual touchdowns and incorporate regression candidate values119        sns.scatterplot(120            x="Expected touchdowns",121            y="Actual touchdowns",122            hue="Positive regression candidate",123            data=data,124            palette=['r', 'g']125        )126        # plot line denoting border to positive/negative regression candidate127        max_actual_td = int(data["Actual touchdowns"].max())128        max_expected_td = int(data["Expected touchdowns"].max())129        max_td = max(max_actual_td, max_expected_td)130        sns.lineplot(x=range(max_td), y=range(max_td))131        # show top five negative and positive regression candidates132        data_sorted = data.sort_values(by="Regression candidate", ascending=False).reset_index()133        for i, row in data_sorted.iterrows():134            if i <= 1 or i >= len(data_sorted) - 1 - 1:135                ax.text(136                    x=row["Expected touchdowns"] + 0.1,137                    y=row["Actual touchdowns"] + 0.05,138                    s=row["player"]139                )140        # save141        data_sorted.to_csv(142            f"../reports/td_regression_candidates/td_regression_candidates_{play}_{position}_{year}.csv",143            index=False144        )145        plt.savefig(146            f"../reports/td_regression_candidates/regression_candidates_{play}_{position}_{year}.png"...TDRegressionCandidates.py
Source:TDRegressionCandidates.py  
1# To add a new cell, type '# %%'2# To add a new markdown cell, type '# %% [markdown]'3# %%4import os5import sys6src_dir = os.path.join(os.getcwd())7abs_path = os.path.abspath(os.path.join(src_dir, os.pardir, 'src'))8sys.path.append(abs_path)9from utils import GLOBAL, functions10# %%11import pandas as pd12import nflfastpy as nfl13from matplotlib import pyplot as plt14import numpy as np15import seaborn as sns16sns.set_style('darkgrid')17# %%18#Change start and end for range19pbp_df = pd.DataFrame()20year_start = 201521year_end = 202022# %%23#Get roster based on last season, change date to last seasons24roster = nfl.load_2020_roster_data()25# %%26#Get yearly pbp data for past 5 years WARNING: Takes a long time27for year in range(year_start, year_end):28    yearly_df = nfl.load_pbp_data(year)29    pbp_df = pd.concat([pbp_df, yearly_df])30# %%31#Filter rushing data32#rush_attempt = 1 if it was a rush_attempt, same with rush_touchdown, & two_point_attempt = 0 to filter out 2pt conversions33rushing_df = pbp_df[['rush_attempt', 'rush_touchdown', 'yardline_100', 'two_point_attempt']]34rushing_df = rushing_df.loc[35    (rushing_df['two_point_attempt'] == 0) & (rushing_df['rush_attempt'] == 1)36]37# %%38#Filter receiving data39#pass_attempt = 1 if it was a rush_attempt, same with pass_touchdown, & two_point_attempt = 0 to filter out 2pt conversions40receiving_df = pbp_df[['pass_attempt', 'pass_touchdown', 'yardline_100', 'two_point_attempt']]41receiving_df = receiving_df.loc[42    (receiving_df['two_point_attempt'] == 0) & (receiving_df['pass_attempt'] == 1)43]44# %%45#Here, we are grouping by the yardline from where the play began, and then using value counts to count the number of times a rushing play was a touchdown (either a 0 or a 1), we can set the argument normalize = True to be able to calculate the proportion of plays that were touchdowns, instead of the count.46rushing_df_probs = rushing_df.groupby('yardline_100')['rush_touchdown'].value_counts(normalize=True)47rushing_df_probs = pd.DataFrame({48    'probability_of_td': rushing_df_probs.values49}, index=rushing_df_probs.index).reset_index()50#Filter out prob of not a td51rushing_df_probs = rushing_df_probs.loc[rushing_df_probs['rush_touchdown'] == 1]52rushing_df_probs = rushing_df_probs.drop('rush_touchdown', axis=1)53# %%54receiving_df_probs = receiving_df.groupby('yardline_100')['pass_touchdown'].value_counts(normalize=True)55receiving_df_probs = pd.DataFrame({56    'probability_of_td': receiving_df_probs.values57}, index=receiving_df_probs.index).reset_index()58#Filter out prob of not a td59receiving_df_probs = receiving_df_probs.loc[receiving_df_probs['pass_touchdown'] == 1]60receiving_df_probs = receiving_df_probs.drop('pass_touchdown', axis=1)61# %%62#Get PBP from the last season which is year_end variable63last_season_pbp_df = nfl.load_pbp_data(year_end)64# %%65#Filter out positions from last years rosters66#RBs67rb_df = roster.loc[roster['position'] == 'RB']['gsis_id']68#WRs69wr_df = roster.loc[roster['position'] == 'WR']['gsis_id']70#TEs71te_df = roster.loc[roster['position'] == 'TE']['gsis_id']72# %% [markdown]73# #RB TD Regression74# %%75#Get rushing data from last season pbp76last_season_RB_rushing_df = last_season_pbp_df.loc[last_season_pbp_df['rush_attempt'] == 1, ['rusher_id', 'rusher_player_name', 'posteam', 'rush_attempt', 'rush_touchdown', 'yardline_100']]77#Filter out RBs78last_season_RB_rushing_df = last_season_RB_rushing_df.loc[last_season_RB_rushing_df['rusher_id'].isin(rb_df)]79#Merge Probability df with Rushing80last_season_RB_rushing_df = last_season_RB_rushing_df.merge(rushing_df_probs, how='left', on='yardline_100')81#Calculate the actual touchdowns rb scored by aggregating all instances where the rush_touchdown == 1 & calculate aggregate of all instances where the probability of scoring a touchdown from that area of the field change names to better reflect what they represent82last_season_RB_rushing_df = last_season_RB_rushing_df.groupby('rusher_id', as_index=False).agg({83    'rusher_player_name': 'first',84    'rush_touchdown': np.sum,85    'probability_of_td': np.sum86}).rename({87    'probability_of_td': 'expected_touchdowns',88    'rush_touchdown': 'actual_touchdowns'89}, axis=1)90#Determine if positive regression candidate by comparing actual scored touchdowns vs expected touchdowns91last_season_RB_rushing_df['positive_regression_candidate'] = last_season_RB_rushing_df['actual_touchdowns'] < last_season_RB_rushing_df['expected_touchdowns']92#Get delta between expected vs actual tds93last_season_RB_rushing_df['delta'] = last_season_RB_rushing_df.apply(94    lambda x: abs(x.expected_touchdowns - x.actual_touchdowns), axis=195)96last_season_RB_rushing_df = last_season_RB_rushing_df.sort_values(by='expected_touchdowns', ascending=False)97# %% [markdown]98# #WR TD Regression99# %%100#Get receiving data from last season pbp101last_season_WR_receiving_df = last_season_pbp_df.loc[last_season_pbp_df['pass_attempt'] == 1, ['receiver_id', 'receiver_player_name', 'posteam', 'pass_attempt', 'pass_touchdown', 'yardline_100']]102#Filter out WRs103last_season_WR_receiving_df = last_season_WR_receiving_df.loc[last_season_WR_receiving_df['receiver_id'].isin(wr_df)]104#Merge Probability df with receiving105last_season_WR_receiving_df = last_season_WR_receiving_df.merge(receiving_df_probs, how='left', on='yardline_100')106#Calculate the actual touchdowns rb scored by aggregating all instances where the rush_touchdown == 1 & calculate aggregate of all instances where the probability of scoring a touchdown from that area of the field change names to better reflect what they represent107last_season_WR_receiving_df = last_season_WR_receiving_df.groupby('receiver_id', as_index=False).agg({108    'receiver_player_name': 'first',109    'pass_touchdown': np.sum,110    'probability_of_td': np.sum111}).rename({112    'probability_of_td': 'expected_touchdowns',113    'pass_touchdown': 'actual_touchdowns'114}, axis=1)115#Determine if positive regression candidate by comparing actual scored touchdowns vs expected touchdowns116last_season_WR_receiving_df['positive_regression_candidate'] = last_season_WR_receiving_df['actual_touchdowns'] < last_season_WR_receiving_df['expected_touchdowns']117#Get delta between expected vs actual tds118last_season_WR_receiving_df['delta'] = last_season_WR_receiving_df.apply(119    lambda x: abs(x.expected_touchdowns - x.actual_touchdowns), axis=1120)121last_season_WR_receiving_df = last_season_WR_receiving_df.sort_values(by='expected_touchdowns', ascending=False)122# %% [markdown]123# #TE TD Regression124# %%125#Get receiving data from last season pbp126last_season_TE_receiving_df = last_season_pbp_df.loc[last_season_pbp_df['pass_attempt'] == 1, ['receiver_id', 'receiver_player_name', 'posteam', 'pass_attempt', 'pass_touchdown', 'yardline_100']]127#Filter out WRs128last_season_TE_receiving_df = last_season_TE_receiving_df.loc[last_season_TE_receiving_df['receiver_id'].isin(te_df)]129#Merge Probability df with receiving130last_season_TE_receiving_df = last_season_TE_receiving_df.merge(receiving_df_probs, how='left', on='yardline_100')131#Calculate the actual touchdowns rb scored by aggregating all instances where the rush_touchdown == 1 & calculate aggregate of all instances where the probability of scoring a touchdown from that area of the field change names to better reflect what they represent132last_season_TE_receiving_df = last_season_TE_receiving_df.groupby('receiver_id', as_index=False).agg({133    'receiver_player_name': 'first',134    'pass_touchdown': np.sum,135    'probability_of_td': np.sum136}).rename({137    'probability_of_td': 'expected_touchdowns',138    'pass_touchdown': 'actual_touchdowns'139}, axis=1)140#Determine if positive regression candidate by comparing actual scored touchdowns vs expected touchdowns141last_season_TE_receiving_df['positive_regression_candidate'] = last_season_TE_receiving_df['actual_touchdowns'] < last_season_TE_receiving_df['expected_touchdowns']142#Get delta between expected vs actual tds143last_season_TE_receiving_df['delta'] = last_season_TE_receiving_df.apply(144    lambda x: abs(x.expected_touchdowns - x.actual_touchdowns), axis=1145)146last_season_TE_receiving_df = last_season_TE_receiving_df.sort_values(by='expected_touchdowns', ascending=False)...Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.
You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.
Get 100 minutes of automation test minutes FREE!!
