{"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":"markdown","source":"# Exploring NFL special teams data for seasons 2018-20","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd \nimport matplotlib.pyplot as plt\nimport scipy.stats as st\nimport seaborn as sns\nimport os, gc, re, warnings\nfrom wordcloud import WordCloud, STOPWORDS\n# from IPython.html import widgets\n# from IPython.display import display\nwarnings.filterwarnings(\"ignore\")","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:31.845960Z","iopub.execute_input":"2021-10-18T16:00:31.846358Z","iopub.status.idle":"2021-10-18T16:00:32.804912Z","shell.execute_reply.started":"2021-10-18T16:00:31.846253Z","shell.execute_reply":"2021-10-18T16:00:32.804159Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Play data","metadata":{}},{"cell_type":"code","source":"plays = pd.read_csv('../input/nfl-big-data-bowl-2022/plays.csv')\nplays['scoreDiff'] = abs(plays.preSnapHomeScore-plays.preSnapVisitorScore)\nplays.head(2)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:32.806265Z","iopub.execute_input":"2021-10-18T16:00:32.807099Z","iopub.status.idle":"2021-10-18T16:00:32.981300Z","shell.execute_reply.started":"2021-10-18T16:00:32.807046Z","shell.execute_reply":"2021-10-18T16:00:32.980684Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ((ax1,ax2),(ax3,ax4),(ax5,ax6),(ax7,ax8), (ax9,ax10)) = plt.subplots(5,2, figsize=(15,20))\nplays.kickLength.plot.hist(bins=50, title='Kick length', grid=True, ax=ax1)\nplays.loc[plays.kickReturnYardage.notnull()]['kickReturnYardage'].plot.hist(bins=50, title='Return result (yds)', grid=True, ax=ax2)\nplays.playResult.plot.hist(bins=50, title='Play result (yds)', grid=True, ax=ax3)\nplays.yardsToGo.plot.hist(bins=20, title='Yards to go at play start', grid=True, ax=ax4)\nplays.penaltyYards.plot.hist(title='Penalty yards', grid=True, ax=ax5)\nplays.penaltyCodes.value_counts()[:10].plot.bar(title='Penalty codes (top 10)', ax=ax6)\nplays.specialTeamsPlayType.value_counts().plot.bar(title='Play type', ax=ax7)\nplays.specialTeamsResult.value_counts().plot.bar(title='Play result breakdown', ax=ax8)\nplays.loc[plays.passResult.notnull()]['passResult'].value_counts().plot.bar(title='Pass result breakdown', ax=ax9)\nplays.yardlineNumber.plot.hist(bins=20, title='Where plays happen (yardline #)', grid=True, ax=ax10)\nplt.tight_layout()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:32.982416Z","iopub.execute_input":"2021-10-18T16:00:32.982782Z","iopub.status.idle":"2021-10-18T16:00:35.696468Z","shell.execute_reply.started":"2021-10-18T16:00:32.982739Z","shell.execute_reply":"2021-10-18T16:00:35.695462Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, (ax1,ax2) = plt.subplots(1,2, figsize=(15,15))  \nplays.down.value_counts().plot.pie(title='Down when plays happen', ax=ax1)\nplays.quarter.value_counts().plot.pie(title='Quarter when plays happen', ax=ax2)\nplt.tight_layout()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:35.698255Z","iopub.execute_input":"2021-10-18T16:00:35.698574Z","iopub.status.idle":"2021-10-18T16:00:35.996171Z","shell.execute_reply.started":"2021-10-18T16:00:35.698540Z","shell.execute_reply":"2021-10-18T16:00:35.995394Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"comment_words = ''\nstopwords = set(STOPWORDS)\n \n# iterate through the df\nfor val in plays.playDescription:\n     \n    val = str(val)\n \n    tokens = val.split()\n     \n    for i in range(len(tokens)):\n        tokens[i] = tokens[i].lower()\n     \n    comment_words += \" \".join(tokens)+\" \"\n \nwordcloud = WordCloud(width = 800, height = 800,\n                background_color ='white',\n                stopwords = stopwords,\n                min_font_size = 10).generate(comment_words)\n \n# plot WordCloud                       \nplt.figure(figsize = (8, 8), facecolor = None)\nplt.imshow(wordcloud)\nplt.axis('off')\nplt.title('Play description word cloud')\nplt.tight_layout(pad = 0)\n \nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:35.997274Z","iopub.execute_input":"2021-10-18T16:00:35.997764Z","iopub.status.idle":"2021-10-18T16:00:39.073003Z","shell.execute_reply.started":"2021-10-18T16:00:35.997729Z","shell.execute_reply":"2021-10-18T16:00:39.071978Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Scout data","metadata":{}},{"cell_type":"code","source":"scout = pd.read_csv('../input/nfl-big-data-bowl-2022/PFFScoutingData.csv')\nscout.head(2)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:39.074520Z","iopub.execute_input":"2021-10-18T16:00:39.074825Z","iopub.status.idle":"2021-10-18T16:00:39.178000Z","shell.execute_reply.started":"2021-10-18T16:00:39.074789Z","shell.execute_reply":"2021-10-18T16:00:39.177296Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ((ax1,ax2,ax3), (ax4,ax5,ax6)) = plt.subplots(2,3, figsize=(15,8))  \nscout.hangTime.plot.hist(bins=20, grid=True, title='Hangtime (seconds)', ax=ax1)\nscout.loc[scout.kickType.notnull()]['kickType'].value_counts().plot.bar(title='Kick type', ax=ax2)\nscout.loc[scout.kickDirectionActual.notnull()]['kickDirectionActual'].value_counts().plot.bar(title='Kick direction', ax=ax3)\nscout.loc[scout.snapTime.notnull()]['snapTime'].plot.hist(bins=20, grid=True, title='Snap time', ax=ax4)\nscout.loc[scout.kickContactType.notnull()]['kickContactType'].value_counts().plot.bar(title='Kick contact type', ax=ax5)\nscout.loc[scout.returnDirectionActual.notnull()]['returnDirectionActual'].value_counts().plot.bar(title='Return direction', ax=ax6)\nplt.tight_layout()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:39.179294Z","iopub.execute_input":"2021-10-18T16:00:39.179510Z","iopub.status.idle":"2021-10-18T16:00:40.527281Z","shell.execute_reply.started":"2021-10-18T16:00:39.179486Z","shell.execute_reply":"2021-10-18T16:00:40.526687Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Merged scout and play data.","metadata":{}},{"cell_type":"code","source":"# merge scout and plays\nplay_scout = pd.merge(plays, scout, how='left', on=['playId','gameId'])\n# select only numeric columns\nnum_play_scout = play_scout.select_dtypes(include=['int','float'])\n\nprint('Numeric columns:')\nfor x in num_play_scout.columns:\n    print(f'-{x}')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:40.528214Z","iopub.execute_input":"2021-10-18T16:00:40.528532Z","iopub.status.idle":"2021-10-18T16:00:40.599445Z","shell.execute_reply.started":"2021-10-18T16:00:40.528507Z","shell.execute_reply":"2021-10-18T16:00:40.598425Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"corr_df = num_play_scout[['quarter','down','yardsToGo','yardlineNumber',\n                          'penaltyYards','preSnapHomeScore','preSnapVisitorScore',\n                          'kickLength','kickReturnYardage','playResult',\n                          'absoluteYardlineNumber','snapTime','operationTime',\n                          'hangTime']]\n\nplt.figure(figsize=(19, 10))\ncorr = corr_df.corr()\nsns.heatmap(corr, annot=True)\nplt.title('Plays-Scout data correlation heatmap')\nplt.show()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:40.600758Z","iopub.execute_input":"2021-10-18T16:00:40.601466Z","iopub.status.idle":"2021-10-18T16:00:41.947779Z","shell.execute_reply.started":"2021-10-18T16:00:40.601433Z","shell.execute_reply":"2021-10-18T16:00:41.947164Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# creates linear regression plots\ndef regress(input1, input2):\n    \n    temp_df = play_scout[[input1,input2]].dropna(how='any')\n    \n    x = temp_df[input1]\n    y = temp_df[input2]\n    \n    # calculates linear regression\n    (slope, intercept, rvalue, pvalue, stderr) = st.linregress(x,y)\n    x = np.asarray(x, dtype=np.float64)\n    regress_values = x * slope + intercept\n    \n    print(regress_values)\n\n    # plots scatter plot and regresion\n    plt.figure(figsize=(10, 8))\n    plt.scatter(x,y)\n    plt.plot(x,regress_values,\"r-\")\n\n    # annotates graph with equation\n    line_eq = \"y = \" + str(round(slope,2)) + \"x + \" + str(round(intercept,2))\n    plt.annotate(line_eq,xy=(min(x),min(y)),fontsize=15,color=\"red\")\n    plt.xlabel(input1)\n    plt.ylabel(input2)\n    plt.title(f'{input1} vs. {input2}')\n    \n    # prints r squared value from linregress function\n    print(f'The r-squared is: {rvalue}')\n    \nregress('kickReturnYardage','hangTime')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:41.950122Z","iopub.execute_input":"2021-10-18T16:00:41.950802Z","iopub.status.idle":"2021-10-18T16:00:42.207003Z","shell.execute_reply.started":"2021-10-18T16:00:41.950767Z","shell.execute_reply":"2021-10-18T16:00:42.205915Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Player data","metadata":{}},{"cell_type":"code","source":"players = pd.read_csv('../input/nfl-big-data-bowl-2022/players.csv')\nplayers.head(2)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:42.210117Z","iopub.execute_input":"2021-10-18T16:00:42.210409Z","iopub.status.idle":"2021-10-18T16:00:42.236660Z","shell.execute_reply.started":"2021-10-18T16:00:42.210377Z","shell.execute_reply":"2021-10-18T16:00:42.235733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Convert height to feet","metadata":{}},{"cell_type":"code","source":"# convert height to feet\nplayers[['feet','inches']] = players['height'].str.split('-',expand=True)\nplayers['feet'] = players['feet'].astype('int')\nplayers['inches'] = players['inches'].astype('float').fillna(0.0)\nplayers['feet'] = np.where(players.feet>8, players.feet/12, players.feet)\nplayers['feet'] = round(players['feet'] + players['inches']/12, 2)\nplayers = players.drop(columns=['inches'])\nplayers.head(2)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:42.237812Z","iopub.execute_input":"2021-10-18T16:00:42.238041Z","iopub.status.idle":"2021-10-18T16:00:42.267705Z","shell.execute_reply.started":"2021-10-18T16:00:42.238015Z","shell.execute_reply":"2021-10-18T16:00:42.267029Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, (ax1,ax2) = plt.subplots(1,2, figsize=(10,4))\nplayers.feet.plot.hist(bins=10, grid=True, title='Player height (ft)', ax=ax1)\nplayers.weight.plot.hist(bins=20, grid=True, title='Player weight (lbs)', ax=ax2)\nplt.tight_layout()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:42.268643Z","iopub.execute_input":"2021-10-18T16:00:42.269361Z","iopub.status.idle":"2021-10-18T16:00:42.731644Z","shell.execute_reply.started":"2021-10-18T16:00:42.269328Z","shell.execute_reply":"2021-10-18T16:00:42.731013Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"players.groupby('Position')['weight'].mean().sort_values(ascending=False)\\\n    .plot.bar(figsize=(15,5), \n              title='Avg. player weight (lbs) by position', \n              grid=True, \n              ylim=(150,325))\nplt.tight_layout()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:42.732537Z","iopub.execute_input":"2021-10-18T16:00:42.733197Z","iopub.status.idle":"2021-10-18T16:00:43.129396Z","shell.execute_reply.started":"2021-10-18T16:00:42.733168Z","shell.execute_reply":"2021-10-18T16:00:43.128526Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"players.groupby('Position')['feet'].mean().sort_values(ascending=False)\\\n    .plot.bar(figsize=(15,5), \n              title='Avg. player height (ft) by position', \n              grid=True, \n              ylim=(5,7))\nplt.tight_layout()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:43.130719Z","iopub.execute_input":"2021-10-18T16:00:43.130985Z","iopub.status.idle":"2021-10-18T16:00:43.516054Z","shell.execute_reply.started":"2021-10-18T16:00:43.130955Z","shell.execute_reply":"2021-10-18T16:00:43.515223Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Game data","metadata":{}},{"cell_type":"code","source":"games = track = pd.read_csv('../input/nfl-big-data-bowl-2022/games.csv')\ngames.head(2)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:43.517443Z","iopub.execute_input":"2021-10-18T16:00:43.517777Z","iopub.status.idle":"2021-10-18T16:00:43.539625Z","shell.execute_reply.started":"2021-10-18T16:00:43.517751Z","shell.execute_reply":"2021-10-18T16:00:43.538926Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Tracking data","metadata":{}},{"cell_type":"code","source":"track = pd.read_csv('../input/nfl-big-data-bowl-2022/tracking2018.csv')\ntrack.head(2)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:00:43.540875Z","iopub.execute_input":"2021-10-18T16:00:43.541498Z","iopub.status.idle":"2021-10-18T16:01:29.319005Z","shell.execute_reply.started":"2021-10-18T16:00:43.541451Z","shell.execute_reply":"2021-10-18T16:01:29.318121Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('Tracking events:')\ntrack.event.unique()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:01:29.320112Z","iopub.execute_input":"2021-10-18T16:01:29.320321Z","iopub.status.idle":"2021-10-18T16:01:30.326895Z","shell.execute_reply.started":"2021-10-18T16:01:29.320297Z","shell.execute_reply":"2021-10-18T16:01:30.326030Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# convert to timestamp\ntrack['ts'] = pd.to_datetime(track['time']).values.astype(np.int64) // 10 ** 9\ntrack = track.drop(columns=['time'])\ntrack.head(2)","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-10-18T16:01:30.328412Z","iopub.execute_input":"2021-10-18T16:01:30.329073Z","iopub.status.idle":"2021-10-18T16:01:34.742444Z","shell.execute_reply.started":"2021-10-18T16:01:30.329026Z","shell.execute_reply":"2021-10-18T16:01:34.741529Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# messing with aggregations\ntrack.groupby(['playId','nflId']).agg({'x': lambda x: x.iat[-1] - x.iat[0], # x pos difference\n                                       'y': lambda x: x.iat[-1] - x.iat[0], # y pos difference\n                                       's': 'mean',                         # avg speed\n                                       'dis': 'sum',                        # total dist\n                                       'o': 'mean',                         # avg orientation\n                                       'dir': 'mean',                       # avg direction\n                                       'frameId': 'last',                   # number of frames\n                                       'ts': lambda x: x.max() - x.min(),   # play time\n                                       'position': 'first', \n                                       'team': 'first',\n                                       'playDirection': 'first',\n                                       'event': 'first'}\n                                     )","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-10-18T16:01:34.743690Z","iopub.execute_input":"2021-10-18T16:01:34.744211Z","iopub.status.idle":"2021-10-18T16:01:52.607158Z","shell.execute_reply.started":"2021-10-18T16:01:34.744179Z","shell.execute_reply":"2021-10-18T16:01:52.606361Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Eye on the ball","metadata":{}},{"cell_type":"code","source":"ball_df = pd.merge(track.loc[track.team=='football'], plays, how='left', on=['gameId','playId'])","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:01:52.608182Z","iopub.execute_input":"2021-10-18T16:01:52.608385Z","iopub.status.idle":"2021-10-18T16:01:55.160262Z","shell.execute_reply.started":"2021-10-18T16:01:52.608361Z","shell.execute_reply":"2021-10-18T16:01:55.158208Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ((ax1,ax2),(ax3,ax4)) = plt.subplots(2,2, figsize=(15,10))  \nball_df.loc[ball_df.specialTeamsPlayType=='Kickoff'].\\\n    groupby('frameId')['s'].mean()[:100]\\\n    .plot.line(figsize=(10,6),\n               title='Avg. ball speed on kickoff plays (first 100 frames)', \n               ylabel='speed',\n               ax=ax1)\nball_df.loc[ball_df.specialTeamsPlayType=='Punt'].\\\n    groupby('frameId')['s'].mean()[:100]\\\n    .plot.line(figsize=(10,6),\n               title='Avg. ball speed on punt plays (first 100 frames)', \n               ylabel='speed',\n               ax=ax2)\nball_df.loc[ball_df.specialTeamsPlayType=='Field Goal'].\\\n    groupby('frameId')['s'].mean()[:100]\\\n    .plot.line(figsize=(10,6),\n               title='Avg. ball speed on field goal plays (first 100 frames)', \n               ylabel='speed',\n               ax=ax3)\nball_df.loc[ball_df.specialTeamsPlayType=='Extra Point'].\\\n    groupby('frameId')['s'].mean()[:100]\\\n    .plot.line(figsize=(10,6),\n               title='Avg. ball speed on extra point plays (first 100 frames)', \n               ylabel='speed',\n               ax=ax4)\nplt.tight_layout()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:01:55.161970Z","iopub.execute_input":"2021-10-18T16:01:55.162476Z","iopub.status.idle":"2021-10-18T16:01:56.582311Z","shell.execute_reply.started":"2021-10-18T16:01:55.162433Z","shell.execute_reply":"2021-10-18T16:01:56.581362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def ball_speed_plotter(play, game):\n    '''\n    A function to plot ball speed of individual plays and frame id of events. \n    argument=\"playId, gameId\" \n    '''\n    if play not in ball_df.playId.unique():\n        return 'Error: Play number does not exist.'\n    temp_df = ball_df.loc[(ball_df.playId==play) & (ball_df.gameId==game)].reset_index()\n    temp_df['s'].plot.line(figsize=(15, 8), \n                           title=f'Game {game}, play {play} ball speed and events',\n                           xlabel='Frame id',\n                           ylabel='Ball speed')\n    \n    plt.gca().set_ylim(bottom=-3)\n    print('Play events')\n    print('------')\n    for index, row in temp_df.loc[temp_df.event!='None'].iterrows():\n        print(f\"-{row['event']} at frame {row['frameId']}\")\n        plt.axvline(x=row['frameId'], color='r', alpha=.4)\n        plt.annotate(row['event'], xy=(row['frameId'], -2), color='r')\n        \nball_speed_plotter(36, 2018123000)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:01:56.583819Z","iopub.execute_input":"2021-10-18T16:01:56.584172Z","iopub.status.idle":"2021-10-18T16:01:56.832805Z","shell.execute_reply.started":"2021-10-18T16:01:56.584134Z","shell.execute_reply":"2021-10-18T16:01:56.831968Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ball_speed_plotter(892,2018123000)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:01:56.834526Z","iopub.execute_input":"2021-10-18T16:01:56.834824Z","iopub.status.idle":"2021-10-18T16:01:57.056220Z","shell.execute_reply.started":"2021-10-18T16:01:56.834784Z","shell.execute_reply":"2021-10-18T16:01:57.055434Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"ball_speed_plotter(373,2018123000)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:01:57.057818Z","iopub.execute_input":"2021-10-18T16:01:57.058145Z","iopub.status.idle":"2021-10-18T16:01:57.298888Z","shell.execute_reply.started":"2021-10-18T16:01:57.058106Z","shell.execute_reply":"2021-10-18T16:01:57.298183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"del ball_df\ngc.collect()","metadata":{"_kg_hide-input":true,"_kg_hide-output":true,"execution":{"iopub.status.busy":"2021-10-18T16:01:57.300043Z","iopub.execute_input":"2021-10-18T16:01:57.300598Z","iopub.status.idle":"2021-10-18T16:01:57.505895Z","shell.execute_reply.started":"2021-10-18T16:01:57.300557Z","shell.execute_reply":"2021-10-18T16:01:57.505368Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Fake plays","metadata":{}},{"cell_type":"code","source":"# assemble df of fake plays\nall_fakes = {'2018':'','2019':'','2020':''}\nfor year in all_fakes:\n    print(f'Loading {year} data....')\n    df = pd.read_csv(f'../input/nfl-big-data-bowl-2022/tracking{year}.csv')\n    print(f'Filtering fake play data....')\n    fake_play_list = df.loc[df.event.str.contains('fake')]['playId'].unique().tolist()\n    all_fakes[year] = df.loc[df.playId.isin(fake_play_list)]\n    print(f'Freeing memory....')\n    del df\n    gc.collect()\n    print('Done.')\n    \nfake_df = all_fakes['2018'].append(all_fakes['2019']).append(all_fakes['2020'])\n\n# fake_df.to_csv('all_fake_plays.csv')\n\nprint(f'\\nShape of fake_df: {fake_df.shape}\\n')\nfake_df.head(2)","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:01:57.506945Z","iopub.execute_input":"2021-10-18T16:01:57.507295Z","iopub.status.idle":"2021-10-18T16:04:14.692618Z","shell.execute_reply.started":"2021-10-18T16:01:57.507256Z","shell.execute_reply":"2021-10-18T16:04:14.691738Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Merge fake df with player, scout, and play data.","metadata":{}},{"cell_type":"code","source":"# merge fake df with player, scout, and play data\nmerged = pd.merge(fake_df, play_scout, how='left', on=['gameId','playId'])\nmerged = pd.merge(merged, games, how='left', on='gameId')\nmerged = pd.merge(merged, players[['nflId','feet','weight','birthDate','collegeName']], how='left', on='nflId')\n\ndel fake_df\ngc.collect()\n\nmerged[\"playSeason\"] = merged['playId'].astype(str) + '_' + merged['season'].astype(str)\n    \nprint(f'Shape of merged df: {merged.shape}')","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:04:14.695938Z","iopub.execute_input":"2021-10-18T16:04:14.696175Z","iopub.status.idle":"2021-10-18T16:04:16.643208Z","shell.execute_reply.started":"2021-10-18T16:04:14.696149Z","shell.execute_reply":"2021-10-18T16:04:16.642243Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ((ax1,ax2,ax3),(ax4,ax5,ax6)) = plt.subplots(2,3, figsize=(15,8))\nmerged.groupby('playSeason').first().season.value_counts().plot.bar(title='Fake plays by season', ax=ax1)\nmerged.groupby('playSeason')['frameId'].max().plot.hist(grid=True, title='Number of frames in fake plays',ax=ax2)\nmerged.groupby('playSeason').first().playDirection.value_counts().plot.bar(title='Fake play directions', ax=ax3)\nmerged.loc[~merged.event.isin(['None','ball_snap'])].groupby('playSeason').first().event.value_counts()[:20].plot.bar(title='Most common fake play \"events\" (top 20)', ax=ax4)\nmerged.loc[merged.event.str.contains('fake')].groupby('playSeason')['frameId'].mean().plot.hist(bins=15, grid=True, title='Frame id when fake play takes place', ax=ax5)\nmerged.groupby('playSeason').first().scoreDiff.plot.hist(grid=True, title='Score diff at time of fake play', ax=ax6)\nplt.tight_layout()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:04:16.644331Z","iopub.execute_input":"2021-10-18T16:04:16.644565Z","iopub.status.idle":"2021-10-18T16:04:21.109064Z","shell.execute_reply.started":"2021-10-18T16:04:16.644539Z","shell.execute_reply":"2021-10-18T16:04:21.107731Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"fig, ((ax1,ax2,ax3),(ax4,ax5,ax6)) = plt.subplots(2,3, figsize=(15,8))\nmerged.groupby('playSeason')['yardlineNumber'].first().plot.hist(bins=15, grid=True, title='Yardline No. where fake play takes place', ax=ax1)\nmerged.groupby('playSeason')['playResult'].first().plot.hist(bins=10, grid=True, title='Fake play results',ax=ax2)\nmerged.groupby('playSeason')['kickType'].first().value_counts().plot.bar(title='Fake play kick types', ax=ax3)\nmerged.groupby('playSeason')['snapDetail'].first().value_counts().plot.pie(title='Snap target', ax=ax4)\nmerged.groupby('playSeason')['possessionTeam'].first().value_counts().plot.bar(title='Teams who do fake plays', ax=ax5)\nmerged.groupby('playSeason')['week'].first().value_counts().sort_index().plot.line(title='Fake plays by week', ax=ax6)\nplt.tight_layout()","metadata":{"_kg_hide-input":true,"execution":{"iopub.status.busy":"2021-10-18T16:04:21.111148Z","iopub.execute_input":"2021-10-18T16:04:21.111507Z","iopub.status.idle":"2021-10-18T16:04:22.705644Z","shell.execute_reply.started":"2021-10-18T16:04:21.111461Z","shell.execute_reply":"2021-10-18T16:04:22.704793Z"},"trusted":true},"execution_count":null,"outputs":[]}]}