{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"code","source":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/input'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))\n\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-01-06T14:27:40.917683Z","iopub.execute_input":"2022-01-06T14:27:40.918277Z","iopub.status.idle":"2022-01-06T14:27:40.951959Z","shell.execute_reply.started":"2022-01-06T14:27:40.918149Z","shell.execute_reply":"2022-01-06T14:27:40.950906Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Load Datasets","metadata":{}},{"cell_type":"code","source":"games_df = pd.read_csv('../input/nfl-big-data-bowl-2022/games.csv')\nPFFScoutingData_df = pd.read_csv('../input/nfl-big-data-bowl-2022/PFFScoutingData.csv')\nplayers_df = pd.read_csv('../input/nfl-big-data-bowl-2022/players.csv')\nplays_df = pd.read_csv('../input/nfl-big-data-bowl-2022/plays.csv')\ntracking2018_df = pd.read_csv('../input/nfl-big-data-bowl-2022/tracking2018.csv')\ntracking2019_df = pd.read_csv('../input/nfl-big-data-bowl-2022/tracking2019.csv')\ntracking2020_df = pd.read_csv('../input/nfl-big-data-bowl-2022/tracking2020.csv')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T14:48:30.437681Z","iopub.execute_input":"2022-01-06T14:48:30.438174Z","iopub.status.idle":"2022-01-06T14:50:54.438591Z","shell.execute_reply.started":"2022-01-06T14:48:30.438141Z","shell.execute_reply":"2022-01-06T14:50:54.43745Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Features Summarization","metadata":{}},{"cell_type":"code","source":"# Function for making feature summary\ndef resumetable(df):\n    print(f'Shape : {df.shape}')\n    summary = pd.DataFrame(df.dtypes, columns=['Data Type'])\n    summary = summary.reset_index()\n    summary = summary.rename(columns={'index': 'Feature'})\n    # Return Series with sum of missing values for each features\n    summary['Num of null'] = df.isnull().sum().values\n    # Return Series with number of distinct elements. Can ignore NaN values.\n    summary['Num of unique'] = df.nunique().values\n    # Show the first three values of all features\n    summary['First value'] = df.loc[0].values\n    summary['Second value'] = df.loc[1].values\n    summary['Third value'] = df.loc[2].values\n    return summary","metadata":{"execution":{"iopub.status.busy":"2022-01-06T14:53:36.035872Z","iopub.execute_input":"2022-01-06T14:53:36.036132Z","iopub.status.idle":"2022-01-06T14:53:36.042942Z","shell.execute_reply.started":"2022-01-06T14:53:36.036104Z","shell.execute_reply":"2022-01-06T14:53:36.042071Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resumetable(games_df)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T14:53:59.253067Z","iopub.execute_input":"2022-01-06T14:53:59.253382Z","iopub.status.idle":"2022-01-06T14:53:59.285114Z","shell.execute_reply.started":"2022-01-06T14:53:59.253347Z","shell.execute_reply":"2022-01-06T14:53:59.284302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resumetable(PFFScoutingData_df)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T14:54:15.740127Z","iopub.execute_input":"2022-01-06T14:54:15.74072Z","iopub.status.idle":"2022-01-06T14:54:15.816391Z","shell.execute_reply.started":"2022-01-06T14:54:15.740677Z","shell.execute_reply":"2022-01-06T14:54:15.815661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resumetable(players_df)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T14:54:39.500721Z","iopub.execute_input":"2022-01-06T14:54:39.501452Z","iopub.status.idle":"2022-01-06T14:54:39.52697Z","shell.execute_reply.started":"2022-01-06T14:54:39.501414Z","shell.execute_reply":"2022-01-06T14:54:39.526373Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resumetable(plays_df)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T14:55:35.149442Z","iopub.execute_input":"2022-01-06T14:55:35.150253Z","iopub.status.idle":"2022-01-06T14:55:35.227106Z","shell.execute_reply.started":"2022-01-06T14:55:35.150188Z","shell.execute_reply":"2022-01-06T14:55:35.226247Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resumetable(tracking2018_df)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T14:55:57.233395Z","iopub.execute_input":"2022-01-06T14:55:57.234033Z","iopub.status.idle":"2022-01-06T14:56:13.816755Z","shell.execute_reply.started":"2022-01-06T14:55:57.233992Z","shell.execute_reply":"2022-01-06T14:56:13.815921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resumetable(tracking2019_df)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T14:56:30.379058Z","iopub.execute_input":"2022-01-06T14:56:30.379785Z","iopub.status.idle":"2022-01-06T14:56:46.055446Z","shell.execute_reply.started":"2022-01-06T14:56:30.379742Z","shell.execute_reply":"2022-01-06T14:56:46.054563Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"resumetable(tracking2020_df)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T14:56:46.056743Z","iopub.execute_input":"2022-01-06T14:56:46.056953Z","iopub.status.idle":"2022-01-06T14:57:01.519144Z","shell.execute_reply.started":"2022-01-06T14:56:46.05693Z","shell.execute_reply":"2022-01-06T14:57:01.518301Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n# _**Analysis on Punt**_","metadata":{}},{"cell_type":"code","source":"# Libraries importation\nimport plotly.express as px\nfrom plotly.subplots import make_subplots\nimport plotly.graph_objs as go\n\npd.set_option('display.max_columns', None)\n\nimport ipywidgets as wg\nfrom IPython.core.display import HTML\nimport matplotlib.animation as anim\nimport matplotlib.pyplot as plt\nimport seaborn as sns","metadata":{"execution":{"iopub.status.busy":"2022-01-06T14:59:13.259667Z","iopub.execute_input":"2022-01-06T14:59:13.260421Z","iopub.status.idle":"2022-01-06T14:59:15.293052Z","shell.execute_reply.started":"2022-01-06T14:59:13.260381Z","shell.execute_reply":"2022-01-06T14:59:15.292258Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**A punter (P) in the NFL is a special teams player who receives the snapped ball directly from the line of scrimmage and then punts (kicks) the football to the opposing team so as to limit any field position advantage. This generally happens on a fourth down in American football and a third down in Canadian football. In this NFL study part, we extensively study the punt by providing significant analysis and its correlation among other features.**\n\n**We firstly studied the different play types of each team and observed we have 4 distinct types of plays: field goal, extra point, punt and kickoff. Among those play types, kickoff is the common play type followed by punt as displayed In below histogram.**","metadata":{}},{"cell_type":"code","source":"plays_df['specialTeamsPlayType'].value_counts().plot.barh(figsize=(8,4), title=\"Special teams plays by type\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:00:40.815863Z","iopub.execute_input":"2022-01-06T15:00:40.816173Z","iopub.status.idle":"2022-01-06T15:00:41.215201Z","shell.execute_reply.started":"2022-01-06T15:00:40.816143Z","shell.execute_reply":"2022-01-06T15:00:41.214252Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Since we are interested in punt play type, we will filter the data according to punt. Therefore, from now, our new data will be related to punt**","metadata":{}},{"cell_type":"code","source":"punt_data = plays_df.loc[plays_df['specialTeamsPlayType'] == 'Punt']\npunt_data.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:02:42.007317Z","iopub.execute_input":"2022-01-06T15:02:42.007702Z","iopub.status.idle":"2022-01-06T15:02:42.044274Z","shell.execute_reply.started":"2022-01-06T15:02:42.007665Z","shell.execute_reply":"2022-01-06T15:02:42.043537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**In the following part of this analysis, we filter the data and only consider those related to the punt play type. What are the statistics regarding the common special team results based on punt? The analysis showed that punt strategy leads more on “return” results. Therefore we will filter the rest of the data according to “return” results**","metadata":{}},{"cell_type":"code","source":"punt_data['specialTeamsResult'].value_counts().plot.barh(figsize=(9,4), title=\"Punt by result\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:03:09.070264Z","iopub.execute_input":"2022-01-06T15:03:09.070568Z","iopub.status.idle":"2022-01-06T15:03:09.286389Z","shell.execute_reply.started":"2022-01-06T15:03:09.070535Z","shell.execute_reply":"2022-01-06T15:03:09.285651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data = punt_data.loc[punt_data['specialTeamsResult'] == 'Return']\npunt_returns_data.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:03:19.685618Z","iopub.execute_input":"2022-01-06T15:03:19.686425Z","iopub.status.idle":"2022-01-06T15:03:19.712627Z","shell.execute_reply.started":"2022-01-06T15:03:19.686383Z","shell.execute_reply":"2022-01-06T15:03:19.711962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Yards gained is important in NFL games. Based on the above filters, we analyzed the length of yards gained by the team based on a punt “return”. Below figure showed that the maximum yard gained frequency is almost 1400 grouped between 0 and 20, more in 10. The boxplot presented that most punt returns are happening around 10 yards, and none reached 100 yards making us believe that a punt does not lead to touchdowns or seldom lead to touchdowns. This theory is further confirmed by data exploration showing that only 5 entries over 2286 reached touchdows, so a percentage of 0.21%. It is relatively small to  consider punt returns as a winning touchdowns strategy.**","metadata":{}},{"cell_type":"code","source":"punt_returns_data[['kickReturnYardage']].plot.hist(figsize=(14,6), title=\"Punt Return Yards gained\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:03:55.874572Z","iopub.execute_input":"2022-01-06T15:03:55.875321Z","iopub.status.idle":"2022-01-06T15:03:56.15365Z","shell.execute_reply.started":"2022-01-06T15:03:55.87528Z","shell.execute_reply":"2022-01-06T15:03:56.152799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ax = punt_returns_data[['possessionTeam', 'kickReturnYardage']].boxplot(by='possessionTeam', figsize=(14,10), vert=False)\nax.set_xlabel(None)\nax.set_title(None)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:04:05.627881Z","iopub.execute_input":"2022-01-06T15:04:05.628269Z","iopub.status.idle":"2022-01-06T15:04:06.355466Z","shell.execute_reply.started":"2022-01-06T15:04:05.62822Z","shell.execute_reply":"2022-01-06T15:04:06.354529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The above boxplot demonstrates that most of punt return are happening around 10 yards, and none reached 100 yards making us believe that punt does not lead to touchdowns.**","metadata":{}},{"cell_type":"code","source":"touch_downs_returns = punt_returns_data.loc[punt_returns_data['playDescription'].str.contains('TOUCHDOWN')]\ntouch_downs_returns.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:04:30.937795Z","iopub.execute_input":"2022-01-06T15:04:30.938755Z","iopub.status.idle":"2022-01-06T15:04:30.969259Z","shell.execute_reply.started":"2022-01-06T15:04:30.938699Z","shell.execute_reply":"2022-01-06T15:04:30.968273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The above results have demonstrated that punt does not lead to touchdowns. This theory is once confirmed by the above dataframe showing only 5 entries over 2286 entries reached  touchdowns, so a percentage of 0.21%. It is relatively small to consider punt returns as winning touchdowns strategy.**","metadata":{}},{"cell_type":"code","source":"ax = touch_downs_returns.groupby('possessionTeam').size().plot.barh(figsize=(14,6), title=\"Punt returns for a TouchDown\")\nax.set_ylabel('Kicking Team')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:05:28.986358Z","iopub.execute_input":"2022-01-06T15:05:28.986678Z","iopub.status.idle":"2022-01-06T15:05:29.282183Z","shell.execute_reply.started":"2022-01-06T15:05:28.986641Z","shell.execute_reply":"2022-01-06T15:05:29.281302Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Refer to one of the tracking data files (tracking2018.csv) so we have the details for the animation:","metadata":{}},{"cell_type":"code","source":"tracking2018_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:06:41.28436Z","iopub.execute_input":"2022-01-06T15:06:41.284698Z","iopub.status.idle":"2022-01-06T15:06:41.309514Z","shell.execute_reply.started":"2022-01-06T15:06:41.284658Z","shell.execute_reply":"2022-01-06T15:06:41.308669Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def getPlayAnimation(df, playId=2626, gameId=2018091000, color_dict={'home': 'red', 'away': 'blue', 'football': 'brown'}):\n    # function to draw one frame\n    def plotFrame(i):\n        one_frame = one_play[ one_play['frameId'] == i+1 ]\n        ax.cla()\n\n        plt.xticks(range(0, 121, 10), fontsize=15)\n        ax.set_xticklabels([None, 'G', '10', '20', '30', '40', '50', '40', '30', '20', '10', 'G', None])\n        ax.tick_params(axis='x', colors='white')\n        \n        # Constants from frame to frame\n        ax.set_xlim([0, 120])\n        ax.set_ylim([0, 53.3])\n        for yardline in range(10, 111, 10):\n            ax.plot([yardline, yardline], [0, 53.3], c='white')\n        \n        # What changes\n        ax.scatter(one_frame['x'], one_frame['y'], c=one_frame['team'].transform(lambda x: color_dict[x]), s=64)\n        ax.set_title('Frame: {}'.format(i+1), fontsize=15, c='white')\n    \n    # Get df of tracking data for one play\n    one_play = df[(df['playId'] == playId) & (df['gameId'] == gameId)]\n    \n    fig, ax = plt.subplots(figsize=(12,6))\n    \n    # Don't show y-axis ticks or tick labels\n    ax.axes.get_yaxis().set_visible(False)\n    \n    # Set background colors\n    fig.patch.set_facecolor('xkcd:leaf green')\n    ax.set_facecolor('xkcd:leaf green')\n    \n    # Set the field border color and line width\n    for spine in ax.spines.values():\n        spine.set_edgecolor('white')\n        spine.set_linewidth(2.5)\n    \n    play_anim = anim.FuncAnimation(fig, plotFrame, frames=one_play['frameId'].max()-1, interval=100)\n    html = play_anim.to_html5_video()\n    plt.close(fig)\n    return HTML(html)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:07:35.693732Z","iopub.execute_input":"2022-01-06T15:07:35.694071Z","iopub.status.idle":"2022-01-06T15:07:35.708039Z","shell.execute_reply.started":"2022-01-06T15:07:35.694024Z","shell.execute_reply":"2022-01-06T15:07:35.707398Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"animation = touch_downs_returns.loc[329]['playDescription']\nanimation","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:08:03.715888Z","iopub.execute_input":"2022-01-06T15:08:03.716685Z","iopub.status.idle":"2022-01-06T15:08:03.723471Z","shell.execute_reply.started":"2022-01-06T15:08:03.716642Z","shell.execute_reply":"2022-01-06T15:08:03.722634Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"team_colors = {'home': 'xkcd:light turquoise',\n               'away': 'xkcd:cobalt',\n               'football': 'xkcd:mud'}\ngetPlayAnimation(tracking2018_df, playId=2626, gameId=2018091000, color_dict=team_colors)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:08:33.914343Z","iopub.execute_input":"2022-01-06T15:08:33.915195Z","iopub.status.idle":"2022-01-06T15:08:53.764612Z","shell.execute_reply.started":"2022-01-06T15:08:33.915145Z","shell.execute_reply":"2022-01-06T15:08:53.763653Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Extract information from scouting data:","metadata":{}},{"cell_type":"code","source":"PFFScoutingData_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:11:00.382112Z","iopub.execute_input":"2022-01-06T15:11:00.382867Z","iopub.status.idle":"2022-01-06T15:11:00.421136Z","shell.execute_reply.started":"2022-01-06T15:11:00.382806Z","shell.execute_reply":"2022-01-06T15:11:00.419921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"PFFScoutingData_df['kickContactType'].value_counts().plot.barh(figsize=(9,4), title=\"Punt by result\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:11:15.65561Z","iopub.execute_input":"2022-01-06T15:11:15.656213Z","iopub.status.idle":"2022-01-06T15:11:15.932122Z","shell.execute_reply.started":"2022-01-06T15:11:15.656169Z","shell.execute_reply":"2022-01-06T15:11:15.931346Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Clean catch from air is the common kick contact type.**","metadata":{}},{"cell_type":"code","source":"# Keep the columns that are related to kickoffs\npunts_cols = ['gameId', 'playId', 'hangTime', 'kickType', 'kickDirectionIntended', 'kickDirectionActual', 'missedTackler',\n                'returnDirectionIntended', 'returnDirectionActual', 'kickoffReturnFormation', 'specialTeamsSafeties','snapDetail',\n               'operationTime','gunners','puntRushers']\nscouting_data_2 = PFFScoutingData_df[punts_cols]\nscouting_data_2.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:12:19.683257Z","iopub.execute_input":"2022-01-06T15:12:19.684252Z","iopub.status.idle":"2022-01-06T15:12:19.710566Z","shell.execute_reply.started":"2022-01-06T15:12:19.684198Z","shell.execute_reply":"2022-01-06T15:12:19.709959Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"scouting_data_2.columns","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:12:31.299569Z","iopub.execute_input":"2022-01-06T15:12:31.300373Z","iopub.status.idle":"2022-01-06T15:12:31.306527Z","shell.execute_reply.started":"2022-01-06T15:12:31.30033Z","shell.execute_reply":"2022-01-06T15:12:31.305722Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Merge the scouting data with the punt that were returned.\npunt_returns_data = punt_returns_data.merge(scouting_data_2, how='left', on=['gameId', 'playId'])\npunt_returns_data.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:12:46.343954Z","iopub.execute_input":"2022-01-06T15:12:46.34445Z","iopub.status.idle":"2022-01-06T15:12:46.405565Z","shell.execute_reply.started":"2022-01-06T15:12:46.344393Z","shell.execute_reply":"2022-01-06T15:12:46.404716Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['kickType'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:12:56.453876Z","iopub.execute_input":"2022-01-06T15:12:56.454171Z","iopub.status.idle":"2022-01-06T15:12:56.463025Z","shell.execute_reply.started":"2022-01-06T15:12:56.454138Z","shell.execute_reply":"2022-01-06T15:12:56.461994Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ax = punt_returns_data[['kickType', 'kickReturnYardage']].boxplot(by='kickType', figsize=(14,6), vert=False)\nax.set_xlabel(None)\nax.set_title(None)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:13:04.778653Z","iopub.execute_input":"2022-01-06T15:13:04.778971Z","iopub.status.idle":"2022-01-06T15:13:04.963899Z","shell.execute_reply.started":"2022-01-06T15:13:04.778936Z","shell.execute_reply":"2022-01-06T15:13:04.963064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Normal - standard punt style is the most play**","metadata":{}},{"cell_type":"code","source":"punt_returns_data['kickoffReturnFormation'].isna().sum()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:13:28.698083Z","iopub.execute_input":"2022-01-06T15:13:28.698829Z","iopub.status.idle":"2022-01-06T15:13:28.706977Z","shell.execute_reply.started":"2022-01-06T15:13:28.69878Z","shell.execute_reply":"2022-01-06T15:13:28.706074Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['returnDirectionIntended'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:13:40.284682Z","iopub.execute_input":"2022-01-06T15:13:40.284965Z","iopub.status.idle":"2022-01-06T15:13:40.293179Z","shell.execute_reply.started":"2022-01-06T15:13:40.284932Z","shell.execute_reply":"2022-01-06T15:13:40.29237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Further analysis on punt shows clean catch from air is the common way on how punt was fielded and normal standard punt style is the most played. The dominant punt direction from the kicking team’s perspective is center, right and then left.**","metadata":{}},{"cell_type":"code","source":"punt_returns_data['returnDirectionIntended'].value_counts().plot.barh(figsize=(9,4), title=\"Punt by result\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:14:02.512275Z","iopub.execute_input":"2022-01-06T15:14:02.513251Z","iopub.status.idle":"2022-01-06T15:14:02.673764Z","shell.execute_reply.started":"2022-01-06T15:14:02.513186Z","shell.execute_reply":"2022-01-06T15:14:02.67286Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['kickDirectionIntended'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:15:19.789508Z","iopub.execute_input":"2022-01-06T15:15:19.790158Z","iopub.status.idle":"2022-01-06T15:15:19.798433Z","shell.execute_reply.started":"2022-01-06T15:15:19.790098Z","shell.execute_reply":"2022-01-06T15:15:19.797655Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['kickDirectionIntended'].value_counts().plot.barh(figsize=(9,4), title=\"Punt by result\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:15:28.573556Z","iopub.execute_input":"2022-01-06T15:15:28.574365Z","iopub.status.idle":"2022-01-06T15:15:28.714289Z","shell.execute_reply.started":"2022-01-06T15:15:28.574299Z","shell.execute_reply":"2022-01-06T15:15:28.71349Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['kickDirectionActual'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:15:41.430272Z","iopub.execute_input":"2022-01-06T15:15:41.431064Z","iopub.status.idle":"2022-01-06T15:15:41.437626Z","shell.execute_reply.started":"2022-01-06T15:15:41.431012Z","shell.execute_reply":"2022-01-06T15:15:41.437064Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['kickDirectionActual'].value_counts().plot.barh(figsize=(9,4), title=\"Punt by result\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:15:48.505434Z","iopub.execute_input":"2022-01-06T15:15:48.506298Z","iopub.status.idle":"2022-01-06T15:15:48.6528Z","shell.execute_reply.started":"2022-01-06T15:15:48.506243Z","shell.execute_reply":"2022-01-06T15:15:48.651957Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['puntRushers'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:15:56.396666Z","iopub.execute_input":"2022-01-06T15:15:56.39713Z","iopub.status.idle":"2022-01-06T15:15:56.405989Z","shell.execute_reply.started":"2022-01-06T15:15:56.397078Z","shell.execute_reply":"2022-01-06T15:15:56.405093Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kickoff_scouting_df_plot = punt_returns_data['puntRushers'].sort_values().head(20)\n\nkickoff_scouting_df_plot.value_counts().head().plot.barh(figsize=(15,14), title=\"Punt by result\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:16:05.229844Z","iopub.execute_input":"2022-01-06T15:16:05.230312Z","iopub.status.idle":"2022-01-06T15:16:05.472736Z","shell.execute_reply.started":"2022-01-06T15:16:05.230268Z","shell.execute_reply":"2022-01-06T15:16:05.471922Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['puntRushers'].value_counts().head().plot.barh(figsize=(19,14), title=\"Punt by result\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:16:21.305264Z","iopub.execute_input":"2022-01-06T15:16:21.305721Z","iopub.status.idle":"2022-01-06T15:16:21.542448Z","shell.execute_reply.started":"2022-01-06T15:16:21.305674Z","shell.execute_reply":"2022-01-06T15:16:21.541638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['gunners'].value_counts()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:16:31.354971Z","iopub.execute_input":"2022-01-06T15:16:31.355269Z","iopub.status.idle":"2022-01-06T15:16:31.364973Z","shell.execute_reply.started":"2022-01-06T15:16:31.355238Z","shell.execute_reply":"2022-01-06T15:16:31.364026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kickoff_scouting_df_plot = scouting_data_2['gunners'].sort_values().head()\n#kickoff_scouting_df_plot = kickoff_scouting_df_plot.head(5)\n\nkickoff_scouting_df_plot.value_counts().plot.barh(figsize=(15,14), title=\"Punt by result\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:16:46.031064Z","iopub.execute_input":"2022-01-06T15:16:46.031761Z","iopub.status.idle":"2022-01-06T15:16:46.292273Z","shell.execute_reply.started":"2022-01-06T15:16:46.031723Z","shell.execute_reply":"2022-01-06T15:16:46.291481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['gunners'].value_counts(5).head().plot.barh(figsize=(19,14), title=\"Punt by result\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:16:57.120221Z","iopub.execute_input":"2022-01-06T15:16:57.121Z","iopub.status.idle":"2022-01-06T15:16:57.381473Z","shell.execute_reply.started":"2022-01-06T15:16:57.120961Z","shell.execute_reply":"2022-01-06T15:16:57.380867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data.columns","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:17:13.702805Z","iopub.execute_input":"2022-01-06T15:17:13.703746Z","iopub.status.idle":"2022-01-06T15:17:13.70918Z","shell.execute_reply.started":"2022-01-06T15:17:13.703701Z","shell.execute_reply":"2022-01-06T15:17:13.708638Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['puntRushers'].head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:17:20.723145Z","iopub.execute_input":"2022-01-06T15:17:20.723711Z","iopub.status.idle":"2022-01-06T15:17:20.730343Z","shell.execute_reply.started":"2022-01-06T15:17:20.723672Z","shell.execute_reply":"2022-01-06T15:17:20.729589Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['kickReturnYardage'].head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:18:22.880886Z","iopub.execute_input":"2022-01-06T15:18:22.881298Z","iopub.status.idle":"2022-01-06T15:18:22.887558Z","shell.execute_reply.started":"2022-01-06T15:18:22.881267Z","shell.execute_reply":"2022-01-06T15:18:22.886981Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"scouting_data_2['hangTime'].plot.kde(figsize=(14, 3), title=\"Distribution of Kickoff Hang Times (s)\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:18:29.985919Z","iopub.execute_input":"2022-01-06T15:18:29.986319Z","iopub.status.idle":"2022-01-06T15:18:30.480798Z","shell.execute_reply.started":"2022-01-06T15:18:29.986291Z","shell.execute_reply":"2022-01-06T15:18:30.480027Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data.plot.scatter(x='hangTime', y='kickReturnYardage', figsize=(14,6), title=\"Kickoff Return Yards vs. Kick Hang Time (s)\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:18:38.653683Z","iopub.execute_input":"2022-01-06T15:18:38.654646Z","iopub.status.idle":"2022-01-06T15:18:38.920978Z","shell.execute_reply.started":"2022-01-06T15:18:38.6546Z","shell.execute_reply":"2022-01-06T15:18:38.920176Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['kickDirectionIntended'].value_counts().plot.barh(figsize=(9,3), title=\"Intended Kick Direction\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:18:46.735852Z","iopub.execute_input":"2022-01-06T15:18:46.73614Z","iopub.status.idle":"2022-01-06T15:18:46.91732Z","shell.execute_reply.started":"2022-01-06T15:18:46.736106Z","shell.execute_reply":"2022-01-06T15:18:46.916561Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\npunt_returns_data['kickDirectionActual'].value_counts().plot.barh(figsize=(9,3), title=\"Actual Kick Direction\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:18:53.355615Z","iopub.execute_input":"2022-01-06T15:18:53.35647Z","iopub.status.idle":"2022-01-06T15:18:53.556277Z","shell.execute_reply.started":"2022-01-06T15:18:53.356433Z","shell.execute_reply":"2022-01-06T15:18:53.555524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"(punt_returns_data['kickDirectionIntended'] == punt_returns_data['kickDirectionActual']).sum() / len(punt_returns_data)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:19:00.206681Z","iopub.execute_input":"2022-01-06T15:19:00.207105Z","iopub.status.idle":"2022-01-06T15:19:00.21508Z","shell.execute_reply.started":"2022-01-06T15:19:00.207077Z","shell.execute_reply":"2022-01-06T15:19:00.214255Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"missed_direction = punt_returns_data[punt_returns_data['kickDirectionIntended'] != punt_returns_data['kickDirectionActual']]\nmissed_direction['kickReturnYardage'].plot.kde(figsize=(14,3), title=\"Distribution of Return Yards on Missed Directional punts\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:19:12.141882Z","iopub.execute_input":"2022-01-06T15:19:12.142297Z","iopub.status.idle":"2022-01-06T15:19:12.373434Z","shell.execute_reply.started":"2022-01-06T15:19:12.142267Z","shell.execute_reply":"2022-01-06T15:19:12.372649Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"missed_tackles_df = punt_returns_data[punt_returns_data['missedTackler'].notnull()]\nmissed_tackles_df['kickReturnYardage'].plot.kde(figsize=(14,3), title=\"Distribution of Return Yards on Missed Tackles\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:19:20.520245Z","iopub.execute_input":"2022-01-06T15:19:20.520526Z","iopub.status.idle":"2022-01-06T15:19:20.735118Z","shell.execute_reply.started":"2022-01-06T15:19:20.520493Z","shell.execute_reply":"2022-01-06T15:19:20.734432Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"missed_tackles_df['missedTackles'] = missed_tackles_df['missedTackler'].str.split(';').str.len()\nmissed_tackles_df['missedTackles'].value_counts().plot.barh(figsize=(9,4), title=\"Returns with Missed Tackles\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:19:27.845027Z","iopub.execute_input":"2022-01-06T15:19:27.845335Z","iopub.status.idle":"2022-01-06T15:19:28.041522Z","shell.execute_reply.started":"2022-01-06T15:19:27.845301Z","shell.execute_reply":"2022-01-06T15:19:28.040666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ax = missed_tackles_df[['missedTackles', 'kickReturnYardage']].boxplot(by='missedTackles', figsize=(14,8), vert=False)\nax.set_xlabel(None)\nax.set_title(None)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:19:40.804784Z","iopub.execute_input":"2022-01-06T15:19:40.805715Z","iopub.status.idle":"2022-01-06T15:19:41.071314Z","shell.execute_reply.started":"2022-01-06T15:19:40.805661Z","shell.execute_reply":"2022-01-06T15:19:41.070554Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data[['gunners', 'puntRushers','specialTeamsSafeties','kickType','kickDirectionActual','kickReturnYardage']].head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:20:00.337011Z","iopub.execute_input":"2022-01-06T15:20:00.33763Z","iopub.status.idle":"2022-01-06T15:20:00.352706Z","shell.execute_reply.started":"2022-01-06T15:20:00.337589Z","shell.execute_reply":"2022-01-06T15:20:00.351729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data['kickReturnYardage'].max()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:20:08.764841Z","iopub.execute_input":"2022-01-06T15:20:08.765105Z","iopub.status.idle":"2022-01-06T15:20:08.771504Z","shell.execute_reply.started":"2022-01-06T15:20:08.765079Z","shell.execute_reply":"2022-01-06T15:20:08.770734Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ax = punt_returns_data[['specialTeamsSafeties', 'kickReturnYardage']].head(100).boxplot(by='specialTeamsSafeties', figsize=(14,8), vert=False)\nax.set_xlabel(None)\nax.set_title(None)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:20:18.650532Z","iopub.execute_input":"2022-01-06T15:20:18.650814Z","iopub.status.idle":"2022-01-06T15:20:19.601787Z","shell.execute_reply.started":"2022-01-06T15:20:18.650786Z","shell.execute_reply":"2022-01-06T15:20:19.600962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**By studying correlation between kick return yardage and hang time, we notice that they are not correlated since their values are below 0. But According to some NFL game statistics, the average hang time for a coffin punt in the NFL was 4.40 seconds, which came at 4.44 seconds the ideal hang time. The below scatter plot shows that for that duration, most of the time, the ball barely exceeds fifty yards.**","metadata":{}},{"cell_type":"code","source":"punt_returns_data_corr = punt_returns_data[['kickReturnYardage','hangTime']].corr()\n\nplt.figure(figsize=(10,4))\nsns.heatmap(punt_returns_data_corr.corr(),annot=False,cmap='summer')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:21:33.571236Z","iopub.execute_input":"2022-01-06T15:21:33.572071Z","iopub.status.idle":"2022-01-06T15:21:33.805462Z","shell.execute_reply.started":"2022-01-06T15:21:33.572008Z","shell.execute_reply":"2022-01-06T15:21:33.804626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data[['kickReturnYardage','hangTime']].corr()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:21:41.662755Z","iopub.execute_input":"2022-01-06T15:21:41.66302Z","iopub.status.idle":"2022-01-06T15:21:41.674983Z","shell.execute_reply.started":"2022-01-06T15:21:41.662992Z","shell.execute_reply":"2022-01-06T15:21:41.674234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"punt_returns_data[['gunners', 'puntRushers','kickDirectionIntended','kickType','kickDirectionActual','kickReturnYardage','hangTime']].head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:21:52.33033Z","iopub.execute_input":"2022-01-06T15:21:52.331131Z","iopub.status.idle":"2022-01-06T15:21:52.348595Z","shell.execute_reply.started":"2022-01-06T15:21:52.331076Z","shell.execute_reply":"2022-01-06T15:21:52.347712Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"p = punt_returns_data[['kickReturnYardage','hangTime']]\nax = p.plot.bar(figsize=(13,13),rot=0)","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:22:36.532731Z","iopub.execute_input":"2022-01-06T15:22:36.533555Z","iopub.status.idle":"2022-01-06T15:23:13.097782Z","shell.execute_reply.started":"2022-01-06T15:22:36.53351Z","shell.execute_reply":"2022-01-06T15:23:13.096947Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.scatterplot(data=p, y=\"kickReturnYardage\", x=\"hangTime\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T15:23:32.997943Z","iopub.execute_input":"2022-01-06T15:23:32.998206Z","iopub.status.idle":"2022-01-06T15:23:33.234214Z","shell.execute_reply.started":"2022-01-06T15:23:32.998178Z","shell.execute_reply":"2022-01-06T15:23:33.233444Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**In this first step, we analyzed the importance of punt in the NFL game. To further our analysis, we will answer above questions and explore more play types (field goal, kickoff, extra point) :**\n - **What is the best punt startegy?**\n - **Who are the best punter?**\n - **How can punt impact the game?**","metadata":{}},{"cell_type":"markdown","source":"---\n# _**Analysis on Field Goal**_","metadata":{}},{"cell_type":"markdown","source":"**Extract Field Goal Play:**","metadata":{}},{"cell_type":"code","source":"play_field_goal = plays_df.loc[plays_df[\"specialTeamsPlayType\"] == \"Field Goal\"]\nprint(\"Total number of Field Goal Play: \", play_field_goal.shape[0])","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:37:41.895483Z","iopub.execute_input":"2022-01-06T17:37:41.895818Z","iopub.status.idle":"2022-01-06T17:37:41.909895Z","shell.execute_reply.started":"2022-01-06T17:37:41.895777Z","shell.execute_reply":"2022-01-06T17:37:41.909104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**By refer to games.csv, we can add 2 features (homeTeamAbbr, visitorTeamAbbr) to the play dataset to determine the home team & away team of each play. Then, we can know that whether the possession team is home team or away team by referring to possessionTeam.**","metadata":{}},{"cell_type":"code","source":"home_team = []\nvisitor_team = []\nfor gameId in play_field_goal[\"gameId\"]:\n    game = games_df[games_df[\"gameId\"]==gameId]\n    home = game.iloc[0,5]\n    visitor = game.iloc[0,6]\n    home_team.append(home)\n    visitor_team.append(visitor)\nplay_field_goal[\"homeTeamAbbr\"] = home_team\nplay_field_goal[\"visitorTeamAbbr\"] = visitor_team\nplay_field_goal.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:37:42.983261Z","iopub.execute_input":"2022-01-06T17:37:42.983903Z","iopub.status.idle":"2022-01-06T17:37:44.372023Z","shell.execute_reply.started":"2022-01-06T17:37:42.983867Z","shell.execute_reply":"2022-01-06T17:37:44.371234Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Add 1 feature about the possession team for the ease of further analysis:**\n* **possessionTeamScore: it will show that whether the situation of possession team's current score, i.e., Leading, Tied, Trailing.**","metadata":{}},{"cell_type":"code","source":"play_field_goal[\"possessionTeamScore\"] = np.nan\n\nplay_field_goal.reset_index(drop=True)\n\nfor index in range(play_field_goal.shape[0]):\n    if play_field_goal.iloc[index, 6] == play_field_goal.iloc[index, -3]:\n        if play_field_goal.iloc[index, 18] > play_field_goal.iloc[index, 19]:\n            play_field_goal.iloc[index, -1] = \"Leading\"\n        elif play_field_goal.iloc[index, 18] < play_field_goal.iloc[index, 19]:\n            play_field_goal.iloc[index, -1] = \"Trailing\"\n        else:\n            play_field_goal.iloc[index, -1] = \"Tied\"\n    else:\n        if play_field_goal.iloc[index, 18] < play_field_goal.iloc[index, 19]:\n            play_field_goal.iloc[index, -1] = \"Leading\"\n        elif play_field_goal.iloc[index, 18] > play_field_goal.iloc[index, 19]:\n            play_field_goal.iloc[index, -1] = \"Trailing\"\n        else:\n            play_field_goal.iloc[index, -1] = \"Tied\"\n\nplay_field_goal.reset_index(drop=True, inplace=True)\nplay_field_goal.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:37:44.373627Z","iopub.execute_input":"2022-01-06T17:37:44.373859Z","iopub.status.idle":"2022-01-06T17:37:45.6724Z","shell.execute_reply.started":"2022-01-06T17:37:44.37383Z","shell.execute_reply":"2022-01-06T17:37:45.671596Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Until this step, we have gathered enough information to do some analysis about the field goal. We will focus on players (field-goal kickers) analysis for the following reasons:**\n* **An important reference in deciding line-up and strategy of game.**\n* **Invaluable information for NFL transfer market.**\n\n**Specifically, we will analyse 3 types of field-goal kickers:**\n* **Highest Mentality : High successful field-goal rate under stress (tied/ trailing)**\n* **Highest Accuracy : High successful field-goal rate overall(without consider the score situation)**\n* **Long-range Expert : Long kick-length with high accuracy**","metadata":{}},{"cell_type":"markdown","source":"### Field-Goal Kickers with Highest Mentality","metadata":{}},{"cell_type":"markdown","source":"**Extract play which the kicker will face high pressure:**","metadata":{}},{"cell_type":"code","source":"play_field_goal_HighPressure = play_field_goal.loc[(play_field_goal[\"possessionTeamScore\"] == \"Tied\") | (play_field_goal[\"possessionTeamScore\"] == \"Trailing\")]\nplay_field_goal_HighPressure.dropna(axis='rows',subset=['kickerId'], inplace=True)\nplay_field_goal_HighPressure.reset_index(drop=True, inplace=True)\nplay_field_goal_HighPressure.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:37:45.674127Z","iopub.execute_input":"2022-01-06T17:37:45.674358Z","iopub.status.idle":"2022-01-06T17:37:45.711263Z","shell.execute_reply.started":"2022-01-06T17:37:45.674328Z","shell.execute_reply":"2022-01-06T17:37:45.710439Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Extract the playerID of those kickers who were under pressure**:","metadata":{}},{"cell_type":"code","source":"field_goal_kicker = play_field_goal_HighPressure.kickerId.unique()\nfield_goal_kicker","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:37:45.999311Z","iopub.execute_input":"2022-01-06T17:37:45.999611Z","iopub.status.idle":"2022-01-06T17:37:46.007751Z","shell.execute_reply.started":"2022-01-06T17:37:45.999567Z","shell.execute_reply":"2022-01-06T17:37:46.006903Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* **Filter out the kickers who barely kick less than 25 times (only consider the kickers with more experience)**\n* **Calculate their successful field-goal rate/ accuracy**","metadata":{}},{"cell_type":"code","source":"kicker_performance = dict()\nfor kicker in field_goal_kicker:\n    kicker_play = play_field_goal_HighPressure.loc[play_field_goal_HighPressure[\"kickerId\"] == kicker]\n    total_kicks = kicker_play.shape[0]\n    good_kicks = (kicker_play.loc[kicker_play[\"specialTeamsResult\"] == \"Kick Attempt Good\"]).shape[0]\n    if total_kicks >= 25:\n        successful_ratio = good_kicks/total_kicks\n        kicker_performance[kicker] = [good_kicks,total_kicks,successful_ratio]\n\nkicker_performance_df = (pd.DataFrame(kicker_performance)).T\nkicker_performance_df.rename(columns={0: 'Number of Good Kick', 1: 'Total Number of Field-Goal Kick', 2: 'Accuracy'}, inplace=True)\nkicker_performance_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:37:46.761776Z","iopub.execute_input":"2022-01-06T17:37:46.762356Z","iopub.status.idle":"2022-01-06T17:37:46.83538Z","shell.execute_reply.started":"2022-01-06T17:37:46.762315Z","shell.execute_reply":"2022-01-06T17:37:46.834596Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Sort the kickers based on their Successful Field-Goal Rate/ Accuracy in descending order:**","metadata":{}},{"cell_type":"code","source":"sorted_kicker_performance = dict(sorted(kicker_performance.items(), key=lambda item: item[1][2],reverse=True))\n\ntop_kicker = []\ntop_kicker_goal_rate = []\nfor key, value in sorted_kicker_performance.items():\n    kicker_name = (players_df.loc[players_df[\"nflId\"] == key]).values[0][6]\n    top_kicker.append(kicker_name)\n    top_kicker_goal_rate.append(value[2])","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:37:48.345753Z","iopub.execute_input":"2022-01-06T17:37:48.346443Z","iopub.status.idle":"2022-01-06T17:37:48.372839Z","shell.execute_reply.started":"2022-01-06T17:37:48.346394Z","shell.execute_reply":"2022-01-06T17:37:48.372072Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Obtain the Top 10 Kickers with Best Mentality:**","metadata":{}},{"cell_type":"code","source":"list_tuples = list(zip(top_kicker[:10], top_kicker_goal_rate[:10]))  \ntop_kicker_df = pd.DataFrame(list_tuples,columns=['Player', 'Accuracy'])\ntop_kicker_df","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:37:49.240523Z","iopub.execute_input":"2022-01-06T17:37:49.240814Z","iopub.status.idle":"2022-01-06T17:37:49.251521Z","shell.execute_reply.started":"2022-01-06T17:37:49.240781Z","shell.execute_reply":"2022-01-06T17:37:49.250773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Visualize the Top 10 Kickers with Best Mentality**","metadata":{}},{"cell_type":"code","source":"import plotly.express as px\nfig = px.bar(top_kicker_df, x='Player', y='Accuracy')\nfig.update_layout(\n    title=\"Kickers with Best Mentality - TOP 10\",\n    title_x=0.5,\n    xaxis_title=\"Player Name\",\n    yaxis_title=\"Accuracy Under Stress\",\n    font=dict(\n        family=\"Old Standard TT\",\n        size=18,\n        color=\"Black\"\n    )\n)\n\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:37:50.233684Z","iopub.execute_input":"2022-01-06T17:37:50.234621Z","iopub.status.idle":"2022-01-06T17:37:50.303891Z","shell.execute_reply.started":"2022-01-06T17:37:50.234548Z","shell.execute_reply":"2022-01-06T17:37:50.302948Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Field-Goal Kickers with Highest Accuracy\n\n**In this part, we will not consider the mentality of kickers based on the score. Instead,  we will rank the kickers based on their successful field-goal rate/ accuracy ONLY.**","metadata":{}},{"cell_type":"markdown","source":"**Extract the playerID of all field-goal kickers**:","metadata":{}},{"cell_type":"code","source":"play_field_goal.dropna(axis='rows',subset=['kickerId'], inplace=True)\nfield_goal_kicker = play_field_goal.kickerId.unique()\nfield_goal_kicker","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:37:54.561633Z","iopub.execute_input":"2022-01-06T17:37:54.562271Z","iopub.status.idle":"2022-01-06T17:37:54.573406Z","shell.execute_reply.started":"2022-01-06T17:37:54.562221Z","shell.execute_reply":"2022-01-06T17:37:54.572567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"* **Filter out the kickers who barely kick less than 25 times (only consider the kickers with more experience)**\n* **Calculate their successful field-goal rate/ accuracy**","metadata":{}},{"cell_type":"code","source":"kicker_performance = dict()\nfor kicker in field_goal_kicker:\n    kicker_play = play_field_goal.loc[play_field_goal[\"kickerId\"] == kicker]\n    total_kicks = kicker_play.shape[0]\n    good_kicks = (kicker_play.loc[kicker_play[\"specialTeamsResult\"] == \"Kick Attempt Good\"]).shape[0]\n    if total_kicks >= 25:\n        successful_ratio = good_kicks/total_kicks\n        kicker_performance[kicker] = [good_kicks,total_kicks,successful_ratio]\n\nkicker_performance_df = (pd.DataFrame(kicker_performance)).T\nkicker_performance_df.rename(columns={0: 'Number of Good Kick', 1: 'Total Number of Field-Goal Kick', 2: 'Accuracy'}, inplace=True)\nkicker_performance_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:37:55.668389Z","iopub.execute_input":"2022-01-06T17:37:55.668665Z","iopub.status.idle":"2022-01-06T17:37:55.741761Z","shell.execute_reply.started":"2022-01-06T17:37:55.668634Z","shell.execute_reply":"2022-01-06T17:37:55.741141Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Sort the kickers based on their Successful Field-Goal Rate/ Accuracy in descending order:**","metadata":{}},{"cell_type":"code","source":"sorted_kicker_performance = dict(sorted(kicker_performance.items(), key=lambda item: item[1][2],reverse=True))\n\ntop_kicker = []\ntop_kicker_goal_rate = []\nfor key, value in sorted_kicker_performance.items():\n    kicker_name = (players_df.loc[players_df[\"nflId\"] == key]).values[0][6]\n    top_kicker.append(kicker_name)\n    top_kicker_goal_rate.append(value[2])","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:37:59.34499Z","iopub.execute_input":"2022-01-06T17:37:59.345699Z","iopub.status.idle":"2022-01-06T17:37:59.374948Z","shell.execute_reply.started":"2022-01-06T17:37:59.345653Z","shell.execute_reply":"2022-01-06T17:37:59.374431Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Obtain the Top 10 Kickers with Best Accuracy:**","metadata":{}},{"cell_type":"code","source":"list_tuples = list(zip(top_kicker[:10], top_kicker_goal_rate[:10]))  \ntop_kicker_df = pd.DataFrame(list_tuples,columns=['Player', 'Accuracy'])\ntop_kicker_df","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:38:02.648128Z","iopub.execute_input":"2022-01-06T17:38:02.648603Z","iopub.status.idle":"2022-01-06T17:38:02.661477Z","shell.execute_reply.started":"2022-01-06T17:38:02.648536Z","shell.execute_reply":"2022-01-06T17:38:02.660662Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Visualize the Top 10 Kickers with Best Accuracy**","metadata":{}},{"cell_type":"code","source":"import plotly.express as px\nfig = px.bar(top_kicker_df, x='Player', y='Accuracy')\nfig.update_layout(\n    title=\"Kickers with Best Accuracy - TOP 10\",\n    title_x=0.5,\n    xaxis_title=\"Player Name\",\n    yaxis_title=\"Accuracy\",\n    font=dict(\n        family=\"Old Standard TT\",\n        size=18,\n        color=\"Black\"\n    )\n)\n\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:38:23.284656Z","iopub.execute_input":"2022-01-06T17:38:23.28494Z","iopub.status.idle":"2022-01-06T17:38:23.352625Z","shell.execute_reply.started":"2022-01-06T17:38:23.284909Z","shell.execute_reply":"2022-01-06T17:38:23.351833Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Field-Goal Kickers (Long-range Expert)\n\n**In this part, we will analyse the long-range expert with high accuracy.**\n\n**We need to add a feature 'average_kicklength' which calculates the average kicklength (successful kick) of each experience kickers (number of kicks > 24) and set a threshold to consider only those kickers who possess accuracy larger than preset threshold, then we will rank the rest of the kickers based on their average kicklength.**\n\n**Threshold:**\n* **Experience/ Number of Field-Goal kicks > 24**\n* **Accuracy > 0.8**","metadata":{}},{"cell_type":"code","source":"kicker_performance = dict()\nfor kicker in field_goal_kicker:\n    kicker_play = play_field_goal.loc[play_field_goal[\"kickerId\"] == kicker]\n    total_kicks = kicker_play.shape[0]\n    kicker_play_good_kick = kicker_play.loc[kicker_play[\"specialTeamsResult\"] == \"Kick Attempt Good\"]\n    total_good_kick_length = sum(kicker_play_good_kick['kickLength'].tolist())\n    good_kicks = kicker_play_good_kick.shape[0]\n    \n    if total_kicks >= 25:\n        average_kicklength = total_good_kick_length/good_kicks\n        successful_ratio = good_kicks/total_kicks\n        if successful_ratio > 0.8:\n            kicker_performance[kicker] = [good_kicks,total_kicks,successful_ratio,average_kicklength]\n\nkicker_performance_df = (pd.DataFrame(kicker_performance)).T\nkicker_performance_df.rename(columns={0: 'Number of Good Kick', 1: 'Total Number of Field-Goal Kick', 2: 'Accuracy', 3: 'Average Kicklength (Yards)'}, inplace=True)\nkicker_performance_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:38:35.735487Z","iopub.execute_input":"2022-01-06T17:38:35.735795Z","iopub.status.idle":"2022-01-06T17:38:35.815621Z","shell.execute_reply.started":"2022-01-06T17:38:35.73576Z","shell.execute_reply":"2022-01-06T17:38:35.814666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Sort the kickers based on their Average Kicklength (Yards) in descending order:**","metadata":{}},{"cell_type":"code","source":"sorted_kicker_performance = dict(sorted(kicker_performance.items(), key=lambda item: item[1][3],reverse=True))\n\ntop_kicker = []\ntop_kicker_goal_rate = []\ntop_kicker_kicklength = []\nfor key, value in sorted_kicker_performance.items():\n    kicker_name = (players_df.loc[players_df[\"nflId\"] == key]).values[0][6]\n    top_kicker.append(kicker_name)\n    top_kicker_goal_rate.append(value[2])\n    top_kicker_kicklength.append(value[3])","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:38:36.583503Z","iopub.execute_input":"2022-01-06T17:38:36.583812Z","iopub.status.idle":"2022-01-06T17:38:36.608131Z","shell.execute_reply.started":"2022-01-06T17:38:36.583768Z","shell.execute_reply":"2022-01-06T17:38:36.607142Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Obtain the Top 10 Long-range Expert:**","metadata":{}},{"cell_type":"code","source":"list_tuples = list(zip(top_kicker[:10], top_kicker_goal_rate[:10], top_kicker_kicklength[:10]))  \ntop_kicker_df = pd.DataFrame(list_tuples,columns=['Player', 'Accuracy', 'Average Kicklength (Yards)'])\ntop_kicker_df","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:38:37.31445Z","iopub.execute_input":"2022-01-06T17:38:37.314956Z","iopub.status.idle":"2022-01-06T17:38:37.328554Z","shell.execute_reply.started":"2022-01-06T17:38:37.314913Z","shell.execute_reply":"2022-01-06T17:38:37.327631Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Visualize the Top 10 Long-Range Expert**","metadata":{}},{"cell_type":"code","source":"import plotly.express as px\nfig = px.bar(top_kicker_df, x='Player', y='Average Kicklength (Yards)')\nfig.update_layout(\n    title=\"Long-range Expert - TOP 10\",\n    title_x=0.5,\n    xaxis_title=\"Player Name\",\n    yaxis_title=\"Average Kicklength (Yards)\",\n    font=dict(\n        family=\"Old Standard TT\",\n        size=18,\n        color=\"Black\"\n    )\n)\n\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T17:38:38.416042Z","iopub.execute_input":"2022-01-06T17:38:38.416298Z","iopub.status.idle":"2022-01-06T17:38:38.484422Z","shell.execute_reply.started":"2022-01-06T17:38:38.41626Z","shell.execute_reply":"2022-01-06T17:38:38.483508Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**From the analysis on Field-Goal Kickers, we can list out some high quality players:**\n* **Player with best mentality (Top 3): Nick Folk, Younghoe Koo, Josh Lambo**\n* **Player with best accuracy (Top 3): Josh Lambo, Graham Gano, Justin Tucker**\n* **Long-range Expert (Top 3): Matt Bryant, Graham Gano, Brandon McManus**\n\n**Besides, we noticed that some names appeared in different categories which show their invaluable value, such as:**\n* **Josh Lambo: Best Mentality - Top 3, Best Accuracy - Top 1, Long-range Expert - Top 10**\n* **Graham Gano: Best Mentality - Top 6, Best Accuracy - Top 2, Long-range Expert - Top 2**\n\n**Their teams should be proud and confidence to have them on the pitch!**","metadata":{}},{"cell_type":"markdown","source":"### Additional： Promising Young Talents\n\n**Due to the lack of data, we will consider the player is still young for those under age of 27.**","metadata":{}},{"cell_type":"code","source":"every_birthDate = []\n\nfor kicker in play_field_goal.kickerId:\n    player = players_df.loc[players_df[\"nflId\"] == kicker]\n    every_birthDate.append(player.birthDate.tolist()[0])\n#print(every_birthDate)\nplay_field_goal['birthDate'] = every_birthDate\nplay_field_goal.fillna(0,inplace=True)\nplay_field_goal.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:29:16.090688Z","iopub.execute_input":"2022-01-06T18:29:16.091103Z","iopub.status.idle":"2022-01-06T18:29:17.218301Z","shell.execute_reply.started":"2022-01-06T18:29:16.091073Z","shell.execute_reply":"2022-01-06T18:29:17.217535Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"age = []\nfor birthdate in play_field_goal.birthDate:\n    if birthdate == 0 :\n        age.append(1000)\n    elif '-' in birthdate:\n        age.append(2020-int(birthdate.split(\"-\")[0]))\n    elif '/' in birthdate:\n        age.append(2020-int(birthdate.split(\"/\")[2]))\nplay_field_goal['age'] = age\nplay_field_goal.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:32:03.50113Z","iopub.execute_input":"2022-01-06T18:32:03.501732Z","iopub.status.idle":"2022-01-06T18:32:03.532409Z","shell.execute_reply.started":"2022-01-06T18:32:03.501697Z","shell.execute_reply":"2022-01-06T18:32:03.531547Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kicker_performance = dict()\nfor kicker in field_goal_kicker:\n    kicker_play = play_field_goal.loc[play_field_goal[\"kickerId\"] == kicker]\n    total_kicks = kicker_play.shape[0]\n    kicker_play_good_kick = kicker_play.loc[kicker_play[\"specialTeamsResult\"] == \"Kick Attempt Good\"]\n    good_kicks = kicker_play_good_kick.shape[0]\n    age = int(kicker_play.age.tolist()[0])\n    #print(age)\n    if total_kicks >= 25:\n        if age <= 27:\n            successful_ratio = good_kicks/total_kicks\n            kicker_performance[kicker] = [good_kicks,total_kicks,successful_ratio,int(age)]\n\nkicker_performance_df = (pd.DataFrame(kicker_performance)).T\nkicker_performance_df.rename(columns={0: 'Number of Good Kick', 1: 'Total Number of Field-Goal Kick', 2: 'Accuracy', 3: 'Age (till 2020)'}, inplace=True)\nkicker_performance_df.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:44:25.534611Z","iopub.execute_input":"2022-01-06T18:44:25.53488Z","iopub.status.idle":"2022-01-06T18:44:25.612975Z","shell.execute_reply.started":"2022-01-06T18:44:25.534851Z","shell.execute_reply":"2022-01-06T18:44:25.612104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sorted_kicker_performance = dict(sorted(kicker_performance.items(), key=lambda item: item[1][2],reverse=True))\n\ntop_kicker = []\ntop_kicker_goal_rate = []\ntop_kicker_age = []\nfor key, value in sorted_kicker_performance.items():\n    kicker_name = (players_df.loc[players_df[\"nflId\"] == key]).values[0][6]\n    top_kicker.append(kicker_name)\n    top_kicker_goal_rate.append(value[2])\n    top_kicker_age.append(value[3])","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:46:07.375Z","iopub.execute_input":"2022-01-06T18:46:07.375615Z","iopub.status.idle":"2022-01-06T18:46:07.389057Z","shell.execute_reply.started":"2022-01-06T18:46:07.375568Z","shell.execute_reply":"2022-01-06T18:46:07.388457Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"list_tuples = list(zip(top_kicker[:10], top_kicker_goal_rate[:10], top_kicker_age[:10]))  \ntop_kicker_df = pd.DataFrame(list_tuples,columns=['Player', 'Accuracy', 'Age (till 2020)'])\ntop_kicker_df","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:46:29.349075Z","iopub.execute_input":"2022-01-06T18:46:29.349397Z","iopub.status.idle":"2022-01-06T18:46:29.362962Z","shell.execute_reply.started":"2022-01-06T18:46:29.349364Z","shell.execute_reply":"2022-01-06T18:46:29.362134Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Visualize Young Talents with Highest Accuracy - TOP 10**","metadata":{}},{"cell_type":"code","source":"import plotly.express as px\nfig = px.bar(top_kicker_df, x='Player', y='Accuracy')\nfig.update_layout(\n    title=\"Young Talents with Highest Accuracy - TOP 10\",\n    title_x=0.5,\n    xaxis_title=\"Player Name\",\n    yaxis_title=\"Accuracy\",\n    font=dict(\n        family=\"Old Standard TT\",\n        size=18,\n        color=\"Black\"\n    )\n)\n\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:47:24.643305Z","iopub.execute_input":"2022-01-06T18:47:24.644256Z","iopub.status.idle":"2022-01-06T18:47:24.71827Z","shell.execute_reply.started":"2022-01-06T18:47:24.644191Z","shell.execute_reply":"2022-01-06T18:47:24.717472Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---\n# _**Analysis on Kickoff**_","metadata":{}},{"cell_type":"code","source":"kickoff = plays_df.loc[plays_df['specialTeamsPlayType'] == 'Kickoff']\nkickoff.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:49:39.784741Z","iopub.execute_input":"2022-01-06T18:49:39.785338Z","iopub.status.idle":"2022-01-06T18:49:39.823418Z","shell.execute_reply.started":"2022-01-06T18:49:39.785296Z","shell.execute_reply":"2022-01-06T18:49:39.822566Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**In this section, we are going to analyse the kickoff from the plays dataset.  \nTherefore, we have to extract kickoff dataset from the origial dataset.**","metadata":{}},{"cell_type":"code","source":"kickoff_col = ['gameId', 'playId', 'hangTime', 'kickType', 'kickDirectionIntended', 'kickDirectionActual', 'tackler',\n                'returnDirectionIntended', 'returnDirectionActual', 'kickoffReturnFormation', 'specialTeamsSafeties']\nscouting_data_2 = PFFScoutingData_df[kickoff_col]\nscouting_data_2.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:51:30.111819Z","iopub.execute_input":"2022-01-06T18:51:30.11245Z","iopub.status.idle":"2022-01-06T18:51:30.136435Z","shell.execute_reply.started":"2022-01-06T18:51:30.112377Z","shell.execute_reply":"2022-01-06T18:51:30.135628Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kickoff = kickoff.merge(scouting_data_2, how='left', on=['gameId', 'playId'])\nkickoff.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:51:58.374979Z","iopub.execute_input":"2022-01-06T18:51:58.375369Z","iopub.status.idle":"2022-01-06T18:51:58.443463Z","shell.execute_reply.started":"2022-01-06T18:51:58.375322Z","shell.execute_reply":"2022-01-06T18:51:58.442704Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Select some features from PFFScouting dataset which may have impact on the performance of kickoff.  \nMerge those selected features on kickoff dataset base on the gameid and playid.**","metadata":{}},{"cell_type":"code","source":"kickoff['specialTeamsResult'].value_counts().plot.barh(figsize=(9,4), title=\"Kickoff by result\")","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:52:21.300004Z","iopub.execute_input":"2022-01-06T18:52:21.300292Z","iopub.status.idle":"2022-01-06T18:52:21.571518Z","shell.execute_reply.started":"2022-01-06T18:52:21.300261Z","shell.execute_reply":"2022-01-06T18:52:21.570611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**As the result shown, the touchback appears most and the return comes the second.  \nThe reason lead to this distribution is that applying touchback while receiving ball is the safest approach action.  \nHowever, if the team want to have some progress, applying return action will be the choice.**","metadata":{}},{"cell_type":"markdown","source":"\n## Analysis on Return Action","metadata":{}},{"cell_type":"code","source":"kickoff_return = kickoff.loc[kickoff['specialTeamsResult'] == 'Return']\nkickoff_return.head()","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:53:42.856804Z","iopub.execute_input":"2022-01-06T18:53:42.857127Z","iopub.status.idle":"2022-01-06T18:53:42.903208Z","shell.execute_reply.started":"2022-01-06T18:53:42.857094Z","shell.execute_reply":"2022-01-06T18:53:42.90246Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ax = kickoff_return[['possessionTeam', 'kickLength']].boxplot(by='possessionTeam', figsize=(14,10), vert=False)\nax.set_xlabel(None)\nax.set_title('KickLength of Each Team')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:54:10.623018Z","iopub.execute_input":"2022-01-06T18:54:10.623451Z","iopub.status.idle":"2022-01-06T18:54:11.418939Z","shell.execute_reply.started":"2022-01-06T18:54:10.623403Z","shell.execute_reply":"2022-01-06T18:54:11.417335Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ax = kickoff_return[['possessionTeam', 'kickReturnYardage']].boxplot(by='possessionTeam', figsize=(14,10), vert=False)\nax.set_xlabel(None)\nax.set_title('KickReturnYardage of Each Team')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:54:19.685565Z","iopub.execute_input":"2022-01-06T18:54:19.685885Z","iopub.status.idle":"2022-01-06T18:54:20.453414Z","shell.execute_reply.started":"2022-01-06T18:54:19.685852Z","shell.execute_reply":"2022-01-06T18:54:20.452635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ax = kickoff_return[['possessionTeam', 'playResult']].boxplot(by='possessionTeam', figsize=(14,10), vert=False)\nax.set_xlabel(None)\nax.set_title('PlayResult of Each Team')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:54:27.991596Z","iopub.execute_input":"2022-01-06T18:54:27.991932Z","iopub.status.idle":"2022-01-06T18:54:29.969971Z","shell.execute_reply.started":"2022-01-06T18:54:27.991895Z","shell.execute_reply":"2022-01-06T18:54:29.968984Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The goal of kickoff is to kick the ball and stop the returning side as far as they can.  \nTherefore, the feature playResult which is the linear combination of the feature kickLength and kickReturnYardage become the performace matric of kickoff.  \nAs the result shown, team TB has the highest median of kickLength, team JAX has the lowest median of kickReturnYardage and team ARI has the highest median of playResult.**","metadata":{}},{"cell_type":"code","source":"ax = kickoff_return[['kickType', 'playResult']].boxplot(by='kickType', figsize=(14,10), vert=False)\nax.set_xlabel(None)\nax.set_title('PlayResult of Each KickType')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:54:46.502646Z","iopub.execute_input":"2022-01-06T18:54:46.502983Z","iopub.status.idle":"2022-01-06T18:54:46.869925Z","shell.execute_reply.started":"2022-01-06T18:54:46.50295Z","shell.execute_reply":"2022-01-06T18:54:46.86868Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The above boxplot show that kickType 'D' have the highest median of playResult.  \nIt's worth noting that the kickType 'S' and 'O' have low median of playResult due to the different purpose of kicking.  \nThe main purpoes of those kickType is to do the onside kick, so the playResult is not that meaningful to them.**","metadata":{}},{"cell_type":"code","source":"touch_downs_returns = kickoff_return.loc[kickoff_return['playDescription'].str.contains('TOUCHDOWN')]\nprint(\"number of kickoff return: {}\".format(len(kickoff_return), 2))\nprint(\"number of kickoff return touch down: {}\".format(len(touch_downs_returns), 2))\nprint(\"kickoff touch down success rate: {} %\".format(round(len(touch_downs_returns)/len(kickoff_return)*100, 3)))","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:55:11.900664Z","iopub.execute_input":"2022-01-06T18:55:11.901705Z","iopub.status.idle":"2022-01-06T18:55:11.9136Z","shell.execute_reply.started":"2022-01-06T18:55:11.901653Z","shell.execute_reply":"2022-01-06T18:55:11.912386Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ax = touch_downs_returns.groupby('possessionTeam').size().plot.barh(figsize=(14,6), title=\"Kickoff returns for a TouchDown\")\nax.set_ylabel('Kicking Team')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:55:23.968371Z","iopub.execute_input":"2022-01-06T18:55:23.969105Z","iopub.status.idle":"2022-01-06T18:55:24.301341Z","shell.execute_reply.started":"2022-01-06T18:55:23.969056Z","shell.execute_reply":"2022-01-06T18:55:24.300487Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"onside_kick = kickoff.loc[kickoff['specialTeamsResult'] == 'Kickoff Team Recovery']\nprint(\"number of kickoff: {}\".format(len(kickoff), 2))\nprint(\"number of onside kick: {}\".format(len(onside_kick), 2))\nprint(\"onside kick success rate: {} %\".format(round(len(onside_kick)/len(kickoff)*100, 3)))","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:55:33.317384Z","iopub.execute_input":"2022-01-06T18:55:33.317706Z","iopub.status.idle":"2022-01-06T18:55:33.327307Z","shell.execute_reply.started":"2022-01-06T18:55:33.317672Z","shell.execute_reply":"2022-01-06T18:55:33.326315Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ax = onside_kick.groupby('possessionTeam').size().plot.barh(figsize=(14,6), title=\"Kickoff returns for a onside kick\")\nax.set_ylabel('Kicking Team')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:55:40.810854Z","iopub.execute_input":"2022-01-06T18:55:40.811291Z","iopub.status.idle":"2022-01-06T18:55:41.073884Z","shell.execute_reply.started":"2022-01-06T18:55:40.811259Z","shell.execute_reply":"2022-01-06T18:55:41.072923Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The results above show the success rate of the return touch down and onside kick, which are the most excited moment of the game.  \nHowever, the success rate is to low to make any anaiysis on it, so the only thing we can do is to plot the frequence of each team.**","metadata":{}},{"cell_type":"code","source":"kickoff_return['possessionTeam'].value_counts().plot.barh(figsize=(20,10), title='Return Times of Each Team')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:56:01.756987Z","iopub.execute_input":"2022-01-06T18:56:01.757278Z","iopub.status.idle":"2022-01-06T18:56:02.195601Z","shell.execute_reply.started":"2022-01-06T18:56:01.757249Z","shell.execute_reply":"2022-01-06T18:56:02.194799Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**As mentioned above, applying return action is more risky than apply touchback action but it can give some advantage to the team.  \nThe follwing section is going to analyse return action.**","metadata":{}},{"cell_type":"code","source":"kick_return = kickoff_return['possessionTeam'].value_counts()\ntotal = kickoff['possessionTeam'].value_counts()\nax = (kick_return / total).sort_values(ascending=False).plot.barh(figsize=(20,10), title='Return rate of Each Team')\nax.bar_label(ax.containers[0])","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:56:20.829893Z","iopub.execute_input":"2022-01-06T18:56:20.830187Z","iopub.status.idle":"2022-01-06T18:56:21.573517Z","shell.execute_reply.started":"2022-01-06T18:56:20.830157Z","shell.execute_reply":"2022-01-06T18:56:21.572415Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The plot above shows that the team DET has the highest probability 57.9% to take return action than the other team and the team CAR has the lowest probability 14.2%.**","metadata":{}},{"cell_type":"code","source":"kickoff_return['kickDirectionActual'].value_counts().plot.barh(figsize=(14,6), title='Return Times of Each KickDirectionActual')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:57:25.241975Z","iopub.execute_input":"2022-01-06T18:57:25.24234Z","iopub.status.idle":"2022-01-06T18:57:25.500133Z","shell.execute_reply.started":"2022-01-06T18:57:25.242299Z","shell.execute_reply":"2022-01-06T18:57:25.498862Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ax = kickoff_return[['kickDirectionActual', 'playResult']].boxplot(by='kickDirectionActual', figsize=(14,6), vert=False)\nax.set_xlabel(None)\nax.set_title('PlayResult of Each KickDirectionActual')","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:57:33.739103Z","iopub.execute_input":"2022-01-06T18:57:33.739847Z","iopub.status.idle":"2022-01-06T18:57:34.002113Z","shell.execute_reply.started":"2022-01-06T18:57:33.739803Z","shell.execute_reply":"2022-01-06T18:57:34.001111Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Analysis of returning over 40 yards","metadata":{}},{"cell_type":"code","source":"return_over40 = kickoff_return.loc[kickoff['playResult'] > 40]","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:58:11.517832Z","iopub.execute_input":"2022-01-06T18:58:11.518136Z","iopub.status.idle":"2022-01-06T18:58:11.52594Z","shell.execute_reply.started":"2022-01-06T18:58:11.518107Z","shell.execute_reply":"2022-01-06T18:58:11.524972Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The next part we are going to take some look on the plays that have playResult over 40 yards.  \nIn this part, we define successful return as return over 40 yards because taking touchback action gerentee the return team 40 yards of playResult.  \nTherefore, considering return over 40 yards as the successful return seem reasonable.**","metadata":{}},{"cell_type":"code","source":"over40 = return_over40['kickDirectionActual'].value_counts()\ntotal = kickoff_return['kickDirectionActual'].value_counts()\nax = (over40 / total).sort_values(ascending=False).plot.barh(figsize=(14,6), title='Return over 40 yard success rate of Each KickDirectionActual')\nax.bar_label(ax.containers[0])","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:58:31.552996Z","iopub.execute_input":"2022-01-06T18:58:31.553843Z","iopub.status.idle":"2022-01-06T18:58:31.783718Z","shell.execute_reply.started":"2022-01-06T18:58:31.553787Z","shell.execute_reply":"2022-01-06T18:58:31.782671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"over40 = return_over40['returnDirectionActual'].value_counts()\ntotal = kickoff_return['returnDirectionActual'].value_counts()\nax = (over40 / total).sort_values(ascending=False).plot.barh(figsize=(14,6), title='Return over 40 yard success rate of Each KickDirectionActual')\nax.bar_label(ax.containers[0])","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:58:38.511438Z","iopub.execute_input":"2022-01-06T18:58:38.511827Z","iopub.status.idle":"2022-01-06T18:58:38.743088Z","shell.execute_reply.started":"2022-01-06T18:58:38.511787Z","shell.execute_reply":"2022-01-06T18:58:38.74214Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"over40 = return_over40['kickType'].value_counts()\ntotal = kickoff_return['kickType'].value_counts()\nax = (over40 / total).sort_values(ascending=False).plot.barh(figsize=(14,6), title='Return over 40 yard success rate of Each KickType')\nax.bar_label(ax.containers[0])","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:58:44.575956Z","iopub.execute_input":"2022-01-06T18:58:44.576238Z","iopub.status.idle":"2022-01-06T18:58:44.804572Z","shell.execute_reply.started":"2022-01-06T18:58:44.576208Z","shell.execute_reply":"2022-01-06T18:58:44.803666Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The results above show that when kicking the ball in left or right direction can make the return team's success lower.  \nHowever, not kick the ball in the center may make the ball out of bounds.  \nMoreover, kicking the ball in the unusial type can also prevent the return team from returning over 40 yards.**","metadata":{}},{"cell_type":"code","source":"over40 = return_over40['possessionTeam'].value_counts()\ntotal = kickoff_return['possessionTeam'].value_counts()\nax = (over40 / total).sort_values(ascending=False).plot.barh(figsize=(20,10), title='Return over 40 yard success rate of Each Team')\nax.bar_label(ax.containers[0])","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:59:13.0931Z","iopub.execute_input":"2022-01-06T18:59:13.093371Z","iopub.status.idle":"2022-01-06T18:59:13.779032Z","shell.execute_reply.started":"2022-01-06T18:59:13.093342Z","shell.execute_reply":"2022-01-06T18:59:13.778188Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**The plot above indicate that the team HOU has the highest success rate 65.7% of return, which means that they have difiiculty on stop the returner before they pushing 40 yards.  \nOn the other hand, if you are the return team it is suggested that taking return action while facing team HOU.**","metadata":{}},{"cell_type":"code","source":"tackle = kickoff.dropna(subset=[\"tackler\"])\nprint(\"number of kickoff: {}\".format(len(kickoff), 2))\nprint(\"number of tackle: {}\".format(len(tackle), 2))\nprint(\"kickoff touch down success rate: {} %\".format(round(len(tackle)/len(kickoff)*100, 3)))","metadata":{"execution":{"iopub.status.busy":"2022-01-06T18:59:34.456113Z","iopub.execute_input":"2022-01-06T18:59:34.456433Z","iopub.status.idle":"2022-01-06T18:59:34.469707Z","shell.execute_reply.started":"2022-01-06T18:59:34.456398Z","shell.execute_reply":"2022-01-06T18:59:34.468718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"---","metadata":{}}]}