{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Can you investigate the relationship between the playing surface and the injury and performance of NFL athletes?"},{"metadata":{},"cell_type":"markdown","source":"## Introduction\nThis page describes the datasets and variables provided to examine the effects that playing on synthetic turf versus natural turf can have on player movements and the factors that may contribute to lower extremity injuries. The data provided for analysis are 250 complete player in-game histories from two subsequent NFL regular seasons. Three different files in .csv format are provided, documenting injuries, player-plays, and player movement during plays. This manual describes the specifics of each variable contained within the datasets as well as guidelines on the best approach to processing the information."},{"metadata":{},"cell_type":"markdown","source":"## The Challenge\nYour challenge is to characterize any differences in player movement between the playing surfaces and to identify specific variables (e.g., field surface, weather, position, play type, etc.) that may influence player movement and the risk of injury. "},{"metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","trusted":true},"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 in \n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nimport matplotlib.pyplot as plt\nimport seaborn as sns\n%matplotlib inline\n# sns.set(style=\"dark\")\n\n# Input data files are available in the \"../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# Any results you write to the current directory are saved as output.","execution_count":null,"outputs":[]},{"metadata":{"_uuid":"d629ff2d2480ee46fbb7e2d37f6b5fab8052498a","_cell_guid":"79c7e3d0-c299-4dcb-8224-4455121ee9b0","trusted":true},"cell_type":"code","source":"PlayList = pd.read_csv('/kaggle/input/nfl-playing-surface-analytics/PlayList.csv')\nPlayerTrackData = pd.read_csv('/kaggle/input/nfl-playing-surface-analytics/PlayerTrackData.csv')\nInjuryRecord = pd.read_csv('/kaggle/input/nfl-playing-surface-analytics/InjuryRecord.csv')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# EDA PlayList"},{"metadata":{"trusted":true},"cell_type":"code","source":"PlayList.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"PlayList.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"PlayList.isna().sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"PlayList.describe(include='all')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"PlayList.RosterPosition.value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"def bar_lables(var, tit, df, size=1):\n    f, ax = plt.subplots(1, 1, figsize=(4*size, 5))\n    total = float(len(df))\n    g = sns.countplot(df[var], order=df[var].value_counts().index, palette='Blues', edgecolor='Navy')\n    g.set_title(f\"Count per {tit}\", fontsize=20)\n    ax.set_xticklabels(ax.get_xticklabels(), rotation=40, ha='right', fontsize=10)\n    for p in ax.patches:\n        height = p.get_height()\n        ax.text(p.get_x() + p.get_width()/2.,\n                height + 3,\n                '{:1.2f}%'.format(100*height/total), ha='center', fontsize=10)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"bar_lables('RosterPosition', 'Position', PlayList, size=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"PlayList.StadiumType.value_counts()","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We notice that there are 3 types with variations in opened and closed and some others, so we have to clear this descriptions:\n* Outdoor\n* Indoor\n* Dome"},{"metadata":{"trusted":true},"cell_type":"code","source":"List_Sta_typ = PlayList[\"StadiumType\"].astype(str).str.strip().str.lower().unique()\n# print(List_Sta_typ)\n\nList_initials = []\n\nfor i in range(len(List_Sta_typ)):\n    List_initials.append(List_Sta_typ[i][0:3])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Let's try to automate this process but I believe I will have to manually intervene some."},{"metadata":{"trusted":true},"cell_type":"code","source":"List_initials = set(List_initials)\n\nfor j in List_initials:\n    print(f\"Initial: {j}\")\n    print(PlayList[PlayList[\"StadiumType\"].fillna(\"\").str.lower().str.startswith(j)].StadiumType.unique())\n    print()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"outdoor = ['Outdoor', 'Outdoors', 'Cloudy', 'Heinz Field', \n              'Outdor', 'Ourdoor', 'Outside', 'Outddors', \n              'Outdoor Retr Roof-Open', 'Oudoor', 'Bowl']\n\nindoor_closed = ['Indoors', 'Indoor', 'Indoor, Roof Closed', 'Indoor, Roof Closed',\n                   'Retractable Roof', 'Retr. Roof-Closed', 'Retr. Roof - Closed', 'Retr. Roof Closed']\n\nindoor_open = ['Indoor, Open Roof', 'Open', 'Retr. Roof-Open', 'Retr. Roof - Open']\n\ndome_closed = ['Dome', 'Domed, closed', 'Closed Dome', 'Domed', 'Dome, closed']\n\ndome_open = ['Domed, Open', 'Domed, open']\n\nList_Types_Stat = [outdoor, indoor_closed, indoor_open, dome_closed, dome_open]","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"conditions_stadium = [PlayList['StadiumType'].isin(outdoor),\n                      PlayList['StadiumType'].isin(indoor_closed),\n                      PlayList['StadiumType'].isin(indoor_open),\n                      PlayList['StadiumType'].isin(dome_closed),\n                      PlayList['StadiumType'].isin(dome_open)]\n\nList_Types_Stat_name = [\"outdoor\", \"indoor_closed\", \"indoor_opened\", \"dome_closed\", \"dome_opened\"]\n\nPlayList['StadiumType_cl'] = np.select(conditions_stadium, List_Types_Stat_name, default='others')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"PlayList['StadiumType_cl'].unique() # Cleaned data for Stadium Type","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plt.figure(figsize=(10,6))\n# ax = sns.countplot(x='StadiumType_cl', order=PlayList.StadiumType_cl.value_counts().index, data=PlayList)\n# ax.set_xticklabels(ax.get_xticklabels(), rotation=40, ha='right')\n# plt.title(\"Qty per Stadium Type\")\n# plt.tight_layout()\n\nbar_lables('StadiumType_cl', 'Statium Type', PlayList, size=4)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"PlayList['FieldType'].value_counts(normalize=True) * 100","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# # sns.countplot(x='FieldType', data = PlayList)\n# # plt.title(\"Qty per FieldType\")\n\n# bar_lables('FieldType', 'Field Type', PlayList)\n\ncolors = ['royalblue', 'cornflowerblue']\n\nPlayList.FieldType.str.get_dummies().sum().plot.pie(label='FieldType', \n                                                    autopct='%1.0f%%', \n                                                    colors=colors, startangle=90, fontsize=15)\nplt.axis('equal');","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# plt.figure(figsize=(10,8))\n# sns.countplot(x='FieldType', hue='StadiumType_cl', data = PlayList)\n\ng = sns.catplot(x='StadiumType_cl', col='FieldType', data=PlayList, kind='count',\n                height=6, palette='Blues', aspect=.7)\ng.set_xticklabels(rotation=45)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# EDA Data Injury Record"},{"metadata":{"trusted":true},"cell_type":"code","source":"InjuryRecord.head()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"InjuryRecord['BodyPart'].value_counts()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(10,6))\nax = sns.countplot(x='BodyPart', order=InjuryRecord.BodyPart.value_counts().index, data=InjuryRecord, palette='Blues')\nax.set_xticklabels(ax.get_xticklabels(), rotation=40, ha='right')\nplt.title(\"Qty per Body Part\")\nplt.tight_layout()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"InjuryRecord","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.catplot(x='BodyPart', col='Surface', data=InjuryRecord, kind='count',\n                height=6, palette='Blues', aspect=.7)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# InjuryRecord.loc.groupby('BodyPart').sum()\nInjuryRecord[['BodyPart','DM_M1','DM_M7','DM_M28','DM_M42']].groupby('BodyPart').sum()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Inj_Surf_BodyPart = InjuryRecord.groupby(['Surface','BodyPart'])['DM_M1','DM_M7','DM_M28','DM_M42'].sum().reset_index()\nInj_Surf_BodyPart","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"As these columns, \"DM_M\" represent the same information, with varying days, let's change to just one column and visualize."},{"metadata":{"trusted":true},"cell_type":"code","source":"Inj_Surf_BodyPart_New = pd.melt(Inj_Surf_BodyPart, id_vars=['Surface','BodyPart'], value_vars=['DM_M1','DM_M7','DM_M28','DM_M42'])\n\nsns.catplot(x='BodyPart', y='value', hue='Surface', col='variable',\n            data=Inj_Surf_BodyPart_New, kind='bar', height=4, aspect=.7, palette='Blues')","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Most missed days are from 1 to 6."},{"metadata":{},"cell_type":"markdown","source":"# EDA Merging the datasets PlayList with InjuryRecord"},{"metadata":{"trusted":true},"cell_type":"code","source":"Relations_table = pd.merge(PlayList, InjuryRecord, how='left', on='PlayerKey')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"col = ['PlayerKey', 'RosterPosition', 'PlayerDay', 'FieldType', 'Temperature', 'PlayType', 'Position', 'PositionGroup',\n       'StadiumType_cl', 'BodyPart', 'Surface', 'DM_M1', 'DM_M7', 'DM_M28', 'DM_M42']\n\nRelations_table = Relations_table[col].copy()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Relations_table.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.heatmap(Relations_table.isnull(), cbar=False)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Now, we have many missed data. For this analysis we will remove any rows with missing data."},{"metadata":{"trusted":true},"cell_type":"code","source":"Relations_table.dropna(inplace=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Relations_table.info()","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"Relations_table","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(16,8))\ng = sns.countplot(y=\"PlayType\", hue=\"Surface\", \n                  order=Relations_table['PlayType'].value_counts().index, \n                  data=Relations_table, palette='Blues')\nplt.title(\"Compare PlayType per Surface\", fontsize=20)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"We noticed no difference and are the two with the largest number of injuries, independent of the field type."},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.catplot(x=\"Temperature\", y=\"Surface\", row=\"BodyPart\",\n                kind=\"box\", orient=\"h\", height=1.5, aspect=5,\n                data=Relations_table.query(\"Temperature > 0\"), palette='Blues');","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"sns.catplot(x=\"Temperature\", y=\"Surface\", row=\"PlayType\",\n                kind=\"box\", orient=\"h\", height=1.5, aspect=5,\n                data=Relations_table.query(\"Temperature > 0\"), palette='Blues');","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"The temperature is not relevant."},{"metadata":{"trusted":true},"cell_type":"code","source":"plt.figure(figsize=(16,8))\ng = sns.countplot(y=\"Position\", hue=\"Surface\", \n                  order=Relations_table['Position'].value_counts().index, \n                  data=Relations_table, palette='Blues')\nplt.title(\"Injuries: Position per Surface\", fontsize=20)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Will be continued, it is not finished..."}],"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":4,"nbformat_minor":1}