{"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":"# Graphs for kicker and returner. ","metadata":{}},{"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)\nimport networkx as nx\nimport matplotlib.pyplot as plt # for plot\nfrom matplotlib.pyplot import figure\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":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Load the plays.csv data using DataFrame from pandas library.","metadata":{}},{"cell_type":"code","source":"scout= pd.read_csv(\"../input/nfl-big-data-bowl-2022/PFFScoutingData.csv\")\ngames = pd.read_csv(\"../input/nfl-big-data-bowl-2022/games.csv\")\nplayers = pd.read_csv(\"../input/nfl-big-data-bowl-2022/players.csv\")\nplays = pd.read_csv(\"../input/nfl-big-data-bowl-2022/plays.csv\")","metadata":{"execution":{"iopub.status.busy":"2021-11-28T14:58:20.488469Z","iopub.execute_input":"2021-11-28T14:58:20.488758Z","iopub.status.idle":"2021-11-28T14:58:20.623458Z","shell.execute_reply.started":"2021-11-28T14:58:20.488726Z","shell.execute_reply":"2021-11-28T14:58:20.622636Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plays.head()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T14:58:24.480192Z","iopub.execute_input":"2021-11-28T14:58:24.480517Z","iopub.status.idle":"2021-11-28T14:58:24.505587Z","shell.execute_reply.started":"2021-11-28T14:58:24.480481Z","shell.execute_reply":"2021-11-28T14:58:24.504844Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"check plays data shape","metadata":{}},{"cell_type":"code","source":"plays.shape","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:08:41.050385Z","iopub.execute_input":"2021-11-28T15:08:41.050903Z","iopub.status.idle":"2021-11-28T15:08:41.056512Z","shell.execute_reply.started":"2021-11-28T15:08:41.050870Z","shell.execute_reply":"2021-11-28T15:08:41.055574Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preprocess the dataset.","metadata":{}},{"cell_type":"code","source":"#count the number of special team for each play type\nplays_specialTeams = plays.groupby('specialTeamsPlayType')\nplays_specialTeams['specialTeamsPlayType'].count()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:11:32.382201Z","iopub.execute_input":"2021-11-28T15:11:32.382574Z","iopub.status.idle":"2021-11-28T15:11:32.397316Z","shell.execute_reply.started":"2021-11-28T15:11:32.382534Z","shell.execute_reply":"2021-11-28T15:11:32.396671Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#show only the important data related to task, and copy from original data frame\n\nplaysdata= plays[['gameId','kickerId','specialTeamsPlayType','specialTeamsResult','possessionTeam','returnerId']]\nplaysdata.head()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:11:37.352147Z","iopub.execute_input":"2021-11-28T15:11:37.352409Z","iopub.status.idle":"2021-11-28T15:11:37.367319Z","shell.execute_reply.started":"2021-11-28T15:11:37.352382Z","shell.execute_reply":"2021-11-28T15:11:37.366477Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"playsdata.shape","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:11:52.230704Z","iopub.execute_input":"2021-11-28T15:11:52.231017Z","iopub.status.idle":"2021-11-28T15:11:52.237379Z","shell.execute_reply.started":"2021-11-28T15:11:52.230976Z","shell.execute_reply":"2021-11-28T15:11:52.236334Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#grouping and counting data by PlayType, Teamresult, and returnerId\n\ngroupPlays = playsdata.groupby(['specialTeamsPlayType','specialTeamsResult'])['returnerId'].count()\ngroupPlays","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:12:03.652869Z","iopub.execute_input":"2021-11-28T15:12:03.653845Z","iopub.status.idle":"2021-11-28T15:12:03.668340Z","shell.execute_reply.started":"2021-11-28T15:12:03.653760Z","shell.execute_reply":"2021-11-28T15:12:03.667678Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#check null value\n\nplaysdata.isnull().sum()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:12:12.469151Z","iopub.execute_input":"2021-11-28T15:12:12.469579Z","iopub.status.idle":"2021-11-28T15:12:12.480898Z","shell.execute_reply.started":"2021-11-28T15:12:12.469546Z","shell.execute_reply":"2021-11-28T15:12:12.480066Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#drop null value\nplaysdata= playsdata.dropna()\nplaysdata","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:12:33.166217Z","iopub.execute_input":"2021-11-28T15:12:33.166473Z","iopub.status.idle":"2021-11-28T15:12:33.191990Z","shell.execute_reply.started":"2021-11-28T15:12:33.166445Z","shell.execute_reply":"2021-11-28T15:12:33.191076Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"playsdata.isnull().sum()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:12:45.645172Z","iopub.execute_input":"2021-11-28T15:12:45.645464Z","iopub.status.idle":"2021-11-28T15:12:45.655148Z","shell.execute_reply.started":"2021-11-28T15:12:45.645432Z","shell.execute_reply":"2021-11-28T15:12:45.654320Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#check duplicate data\nplaysData = playsdata.groupby(['gameId','possessionTeam', 'specialTeamsPlayType','specialTeamsResult','kickerId','returnerId'])\nplaysData['returnerId'].count()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:12:59.154817Z","iopub.execute_input":"2021-11-28T15:12:59.155366Z","iopub.status.idle":"2021-11-28T15:12:59.174549Z","shell.execute_reply.started":"2021-11-28T15:12:59.155320Z","shell.execute_reply":"2021-11-28T15:12:59.173791Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#drop duplicate data\nplaysdata= playsdata.drop_duplicates()\nplaysdata","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:13:25.923118Z","iopub.execute_input":"2021-11-28T15:13:25.923397Z","iopub.status.idle":"2021-11-28T15:13:25.942693Z","shell.execute_reply.started":"2021-11-28T15:13:25.923365Z","shell.execute_reply":"2021-11-28T15:13:25.942053Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"playsdata.shape","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:13:59.396592Z","iopub.execute_input":"2021-11-28T15:13:59.397006Z","iopub.status.idle":"2021-11-28T15:13:59.403554Z","shell.execute_reply.started":"2021-11-28T15:13:59.396975Z","shell.execute_reply":"2021-11-28T15:13:59.402766Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Graph Construction and Visualization","metadata":{}},{"cell_type":"markdown","source":"## Undirect graph\n\nAn undirected chart is a more restrictive chart type. They only represent whether there is a relationship between two nodes or not. However they do not represent the difference between subject and object in that relationship. to represent between kicker and returner for the whole data, it is better to use indirect without considering the relation between kicker and receiver. If using a direct graph, the relationship must be built by looking at the data per each team.","metadata":{}},{"cell_type":"code","source":"# Add all columns in the table as edge attribute\nG = nx.from_pandas_edgelist(playsdata, 'kickerId', 'returnerId', edge_attr=True )","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:15:27.062242Z","iopub.execute_input":"2021-11-28T15:15:27.062740Z","iopub.status.idle":"2021-11-28T15:15:27.084166Z","shell.execute_reply.started":"2021-11-28T15:15:27.062708Z","shell.execute_reply":"2021-11-28T15:15:27.083303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#check the edges\nG.edges(data=True)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:15:39.524838Z","iopub.execute_input":"2021-11-28T15:15:39.525130Z","iopub.status.idle":"2021-11-28T15:15:39.551596Z","shell.execute_reply.started":"2021-11-28T15:15:39.525098Z","shell.execute_reply":"2021-11-28T15:15:39.550930Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#check the nodes\nG.nodes()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:16:10.230739Z","iopub.execute_input":"2021-11-28T15:16:10.231054Z","iopub.status.idle":"2021-11-28T15:16:10.237039Z","shell.execute_reply.started":"2021-11-28T15:16:10.231024Z","shell.execute_reply":"2021-11-28T15:16:10.236245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(nx.info(G))","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:16:24.361702Z","iopub.execute_input":"2021-11-28T15:16:24.362715Z","iopub.status.idle":"2021-11-28T15:16:24.370419Z","shell.execute_reply.started":"2021-11-28T15:16:24.362664Z","shell.execute_reply":"2021-11-28T15:16:24.369198Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#check the type of Graph\ntype(G)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:16:58.498330Z","iopub.execute_input":"2021-11-28T15:16:58.498572Z","iopub.status.idle":"2021-11-28T15:16:58.503611Z","shell.execute_reply.started":"2021-11-28T15:16:58.498545Z","shell.execute_reply":"2021-11-28T15:16:58.502827Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#check data type of playsdata frame\nplaysdata.dtypes","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:17:27.867861Z","iopub.execute_input":"2021-11-28T15:17:27.868754Z","iopub.status.idle":"2021-11-28T15:17:27.876631Z","shell.execute_reply.started":"2021-11-28T15:17:27.868713Z","shell.execute_reply":"2021-11-28T15:17:27.875646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Print out an undirected graph with all the kicker-and-returner graphs.","metadata":{}},{"cell_type":"code","source":"figure(figsize=(20, 20))\nnx.draw_networkx(G, with_labels = True)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:17:47.601557Z","iopub.execute_input":"2021-11-28T15:17:47.601849Z","iopub.status.idle":"2021-11-28T15:17:50.568585Z","shell.execute_reply.started":"2021-11-28T15:17:47.601817Z","shell.execute_reply":"2021-11-28T15:17:50.567730Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#print graph using degree of centrality\n\n# set layout (node position)\npos = nx.spring_layout(G)\n\nbetCent = nx.betweenness_centrality(G, normalized=True, endpoints=True)\nnode_color = [20000.0 * G.degree(v) for v in G]\nnode_size =  [v * 10000 for v in betCent.values()]\nplt.figure(figsize=(20,20))\n\n# draw figure with customized options\nnx.draw(G, pos=pos, with_labels=False,\n                 node_color=node_color,\n                 node_size=node_size )\n\nplt.show()\n# may took some times","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:18:26.697974Z","iopub.execute_input":"2021-11-28T15:18:26.698591Z","iopub.status.idle":"2021-11-28T15:18:29.178017Z","shell.execute_reply.started":"2021-11-28T15:18:26.698556Z","shell.execute_reply":"2021-11-28T15:18:29.177325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Direct Graph for each team\n\nConstruct Direct Graph for each team","metadata":{}},{"cell_type":"code","source":"#change datatype of kicker ID from float to int\nplaysdata['kickerId'] =playsdata['kickerId'].astype(int)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:22:34.600828Z","iopub.execute_input":"2021-11-28T15:22:34.601221Z","iopub.status.idle":"2021-11-28T15:22:34.606435Z","shell.execute_reply.started":"2021-11-28T15:22:34.601192Z","shell.execute_reply":"2021-11-28T15:22:34.605656Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"playsdata.dtypes","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:22:47.640658Z","iopub.execute_input":"2021-11-28T15:22:47.641361Z","iopub.status.idle":"2021-11-28T15:22:47.648519Z","shell.execute_reply.started":"2021-11-28T15:22:47.641318Z","shell.execute_reply":"2021-11-28T15:22:47.647610Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"playsdataGroup = playsdata.groupby('possessionTeam')","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:23:12.869961Z","iopub.execute_input":"2021-11-28T15:23:12.870658Z","iopub.status.idle":"2021-11-28T15:23:12.875135Z","shell.execute_reply.started":"2021-11-28T15:23:12.870613Z","shell.execute_reply":"2021-11-28T15:23:12.874424Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"keys = playsdataGroup.groups.keys()\n\nfor i in keys:\n    G_Data = nx.from_pandas_edgelist(playsdataGroup.get_group(i),source='kickerId',target='returnerId', create_using=nx.DiGraph(),edge_attr=True)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:23:49.522416Z","iopub.execute_input":"2021-11-28T15:23:49.522907Z","iopub.status.idle":"2021-11-28T15:23:49.564474Z","shell.execute_reply.started":"2021-11-28T15:23:49.522873Z","shell.execute_reply":"2021-11-28T15:23:49.563842Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Print out the graph (with larger size than default) for Team \"DET\" with player names on nodes","metadata":{}},{"cell_type":"code","source":"playsdataDET=playsdataGroup.get_group(\"DET\")","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:24:46.794489Z","iopub.execute_input":"2021-11-28T15:24:46.794731Z","iopub.status.idle":"2021-11-28T15:24:46.799338Z","shell.execute_reply.started":"2021-11-28T15:24:46.794705Z","shell.execute_reply":"2021-11-28T15:24:46.798410Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#construct teams DET direct graph\nGDET = nx.from_pandas_edgelist(playsdataDET,source='kickerId',target='returnerId', create_using=nx.DiGraph(),edge_attr='specialTeamsPlayType')","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:25:09.459362Z","iopub.execute_input":"2021-11-28T15:25:09.459647Z","iopub.status.idle":"2021-11-28T15:25:09.465435Z","shell.execute_reply.started":"2021-11-28T15:25:09.459617Z","shell.execute_reply":"2021-11-28T15:25:09.464513Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#print Graph of team DET\n\ndegCent = nx.degree_centrality(GDET)\nnode_color = ['orange' if type(v)==str else 'green' for v in GDET]\nnode_size =  [v * 10000 for v in degCent.values()]\nplt.figure(figsize=(20,20))\n\n# draw figure with customized options\nnx.draw(GDET, with_labels=True,\n                 node_color=node_color,\n                 node_size=node_size)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:26:02.145740Z","iopub.execute_input":"2021-11-28T15:26:02.146178Z","iopub.status.idle":"2021-11-28T15:26:03.373027Z","shell.execute_reply.started":"2021-11-28T15:26:02.146146Z","shell.execute_reply":"2021-11-28T15:26:03.372112Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Bipartie Graph\n\nThe vertices in the graph can be divided into two independent sets. in this case the set is U and V with colors, green and orange. We can also say that there is no edge that connects vertices of same set. A bipartite graph is possible if the graph coloring is possible using two colors such that vertices in a set are colored with the same color.","metadata":{}},{"cell_type":"code","source":"for node in GDET.nodes:\n    if type(node) == str:\n        GDET.nodes[node]['bipartie']='kickerId'\n    elif type(node) == int:\n        GDET.nodes[node]['bipartie']='returnerId'","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:26:37.526432Z","iopub.execute_input":"2021-11-28T15:26:37.526715Z","iopub.status.idle":"2021-11-28T15:26:37.531755Z","shell.execute_reply.started":"2021-11-28T15:26:37.526685Z","shell.execute_reply":"2021-11-28T15:26:37.530962Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"top = {node for node in GDET.nodes if GDET.nodes[node]['bipartie']=='kickerId'}","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:27:19.483372Z","iopub.execute_input":"2021-11-28T15:27:19.483656Z","iopub.status.idle":"2021-11-28T15:27:19.488393Z","shell.execute_reply.started":"2021-11-28T15:27:19.483625Z","shell.execute_reply":"2021-11-28T15:27:19.487542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pos = nx.bipartite_layout(GDET, top)\n\ndegCent = nx.degree_centrality(GDET)\nnode_color = ['orange' if type(v)==str else 'green' for v in GDET]\nnode_size =  [v * 10000 for v in degCent.values()]\nplt.figure(figsize=(20,20))\n\n# draw figure with customized options\nnx.draw(GDET, pos=pos, with_labels=True,\n                 node_color=node_color,\n                 node_size=node_size )\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:27:32.637951Z","iopub.execute_input":"2021-11-28T15:27:32.638437Z","iopub.status.idle":"2021-11-28T15:27:33.898704Z","shell.execute_reply.started":"2021-11-28T15:27:32.638389Z","shell.execute_reply":"2021-11-28T15:27:33.897940Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Extend the graph for Teams \"ATL\" with each returner connected to its corresponding Team","metadata":{}},{"cell_type":"code","source":"#copy only specific coulumn that will be use in task\n\ngamesdata = games[['gameId','homeTeamAbbr','visitorTeamAbbr']]\ngamesdata.head()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:29:00.978465Z","iopub.execute_input":"2021-11-28T15:29:00.978728Z","iopub.status.idle":"2021-11-28T15:29:00.990475Z","shell.execute_reply.started":"2021-11-28T15:29:00.978701Z","shell.execute_reply":"2021-11-28T15:29:00.989680Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"gamesdata.shape","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:29:17.853426Z","iopub.execute_input":"2021-11-28T15:29:17.853870Z","iopub.status.idle":"2021-11-28T15:29:17.859693Z","shell.execute_reply.started":"2021-11-28T15:29:17.853836Z","shell.execute_reply":"2021-11-28T15:29:17.858676Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#add new coulumn name of returner team into first dataframe by gameId\nplaysdata['homeTeam'] =playsdata.gameId.map(gamesdata.set_index('gameId')['homeTeamAbbr'].to_dict())","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:31:19.988606Z","iopub.execute_input":"2021-11-28T15:31:19.989181Z","iopub.status.idle":"2021-11-28T15:31:19.997490Z","shell.execute_reply.started":"2021-11-28T15:31:19.989136Z","shell.execute_reply":"2021-11-28T15:31:19.996677Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"playsdata","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:31:35.431966Z","iopub.execute_input":"2021-11-28T15:31:35.432502Z","iopub.status.idle":"2021-11-28T15:31:35.449344Z","shell.execute_reply.started":"2021-11-28T15:31:35.432452Z","shell.execute_reply":"2021-11-28T15:31:35.448564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"playsdata2=playsdata.merge(games[['gameId','homeTeamAbbr','visitorTeamAbbr']],how='left',left_on=['gameId','possessionTeam'],right_on=['gameId','homeTeamAbbr']).drop('homeTeamAbbr', axis='columns').fillna(games['homeTeamAbbr'])","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:32:51.568084Z","iopub.execute_input":"2021-11-28T15:32:51.568390Z","iopub.status.idle":"2021-11-28T15:32:51.580015Z","shell.execute_reply.started":"2021-11-28T15:32:51.568342Z","shell.execute_reply":"2021-11-28T15:32:51.579340Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in range(len(playsdata2)):\n  if (playsdata2['possessionTeam'][i] != playsdata2['homeTeam'][i]) :\n     playsdata2['visitorTeamAbbr'][i] = playsdata2['homeTeam'][i]","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:33:57.560448Z","iopub.execute_input":"2021-11-28T15:33:57.560885Z","iopub.status.idle":"2021-11-28T15:33:58.173550Z","shell.execute_reply.started":"2021-11-28T15:33:57.560853Z","shell.execute_reply":"2021-11-28T15:33:58.172813Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"playsdata2 = playsdata2.rename(columns={\"visitorTeamAbbr\": \"returnerTeam\"})","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:34:21.035183Z","iopub.execute_input":"2021-11-28T15:34:21.035445Z","iopub.status.idle":"2021-11-28T15:34:21.040949Z","shell.execute_reply.started":"2021-11-28T15:34:21.035418Z","shell.execute_reply":"2021-11-28T15:34:21.040117Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"playsdata2","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:34:33.194523Z","iopub.execute_input":"2021-11-28T15:34:33.195094Z","iopub.status.idle":"2021-11-28T15:34:33.213186Z","shell.execute_reply.started":"2021-11-28T15:34:33.195056Z","shell.execute_reply":"2021-11-28T15:34:33.212212Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"playsdata2Group = playsdata2.groupby('possessionTeam')","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:35:34.139133Z","iopub.execute_input":"2021-11-28T15:35:34.139421Z","iopub.status.idle":"2021-11-28T15:35:34.143685Z","shell.execute_reply.started":"2021-11-28T15:35:34.139389Z","shell.execute_reply":"2021-11-28T15:35:34.143104Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"dataATL=playsdata2Group.get_group(\"ATL\")","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:35:51.389300Z","iopub.execute_input":"2021-11-28T15:35:51.389700Z","iopub.status.idle":"2021-11-28T15:35:51.394579Z","shell.execute_reply.started":"2021-11-28T15:35:51.389660Z","shell.execute_reply":"2021-11-28T15:35:51.393970Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"GATL = nx.from_pandas_edgelist(dataATL,source='returnerId',target='returnerTeam', create_using=nx.DiGraph(),edge_attr='possessionTeam')","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:36:08.479659Z","iopub.execute_input":"2021-11-28T15:36:08.480055Z","iopub.status.idle":"2021-11-28T15:36:08.485445Z","shell.execute_reply.started":"2021-11-28T15:36:08.480025Z","shell.execute_reply":"2021-11-28T15:36:08.484836Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"len(pd.unique(dataATL[\"returnerTeam\"]))","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:36:16.939541Z","iopub.execute_input":"2021-11-28T15:36:16.940016Z","iopub.status.idle":"2021-11-28T15:36:16.946134Z","shell.execute_reply.started":"2021-11-28T15:36:16.939985Z","shell.execute_reply":"2021-11-28T15:36:16.945351Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"color = [\n\"lightcoral\", \"gray\", \"lightgray\", \"firebrick\", \"red\", \"chocolate\", \"darkorange\", \"moccasin\", \"gold\", \"yellow\", \"darkolivegreen\", \"chartreuse\", \"forestgreen\", \"lime\", \"mediumaquamarine\", \"turquoise\", \"teal\", \"cadetblue\", \"purple\", \"blue\", \"slateblue\", \"blueviolet\", \"magenta\", \"lightsteelblue\",\"orange\",\"green\",\"navy\"]","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:36:25.875368Z","iopub.execute_input":"2021-11-28T15:36:25.875659Z","iopub.status.idle":"2021-11-28T15:36:25.881085Z","shell.execute_reply.started":"2021-11-28T15:36:25.875629Z","shell.execute_reply":"2021-11-28T15:36:25.879678Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"colors = []\ni = 0\nfor node in GATL:\n    if node in dataATL[\"returnerId\"].values:\n      colors.append(\"lightgreen\")  \n    else:\n        colors.append(color[i])\n        i+=1\n","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:36:35.398671Z","iopub.execute_input":"2021-11-28T15:36:35.399201Z","iopub.status.idle":"2021-11-28T15:36:35.404985Z","shell.execute_reply.started":"2021-11-28T15:36:35.399168Z","shell.execute_reply":"2021-11-28T15:36:35.404120Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20,20))\n\n# draw figure with customized options\nnx.draw(GATL, with_labels=True,\n                 node_color=colors,\n                 node_size=1200)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:36:46.016461Z","iopub.execute_input":"2021-11-28T15:36:46.016749Z","iopub.status.idle":"2021-11-28T15:36:47.021210Z","shell.execute_reply.started":"2021-11-28T15:36:46.016718Z","shell.execute_reply":"2021-11-28T15:36:47.020635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Graph Analysis","metadata":{}},{"cell_type":"markdown","source":"In thhe directed graph of Team \"DET\", we want to know which player acts the most similar functionality as player 40113. We can calculate the similarity by finding the kick of similiarity between the nodes of each player. below is a code of displaying the similiarity of players who have similiarity to certain players. From the results we can also see which players have the same function as the player number 40113 . ","metadata":{}},{"cell_type":"code","source":"returner_nodes = list(n for n in  GDET.nodes() if type(n) == str)\nlen(returner_nodes)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:38:35.424385Z","iopub.execute_input":"2021-11-28T15:38:35.424746Z","iopub.status.idle":"2021-11-28T15:38:35.432328Z","shell.execute_reply.started":"2021-11-28T15:38:35.424708Z","shell.execute_reply":"2021-11-28T15:38:35.431119Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"kicker_nodes = list(n for n in  GDET.nodes() if type(n) == int)\nlen(kicker_nodes)","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:38:43.115401Z","iopub.execute_input":"2021-11-28T15:38:43.115741Z","iopub.status.idle":"2021-11-28T15:38:43.123019Z","shell.execute_reply.started":"2021-11-28T15:38:43.115705Z","shell.execute_reply":"2021-11-28T15:38:43.122061Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"from collections import defaultdict\n\ndef shared_partition_nodes(G, node1, node2):\n    # Check that the nodes belong to the same partition\n    assert type(node1) == type(node2)\n\n    # Get neighbors of node 1: nbrs1\n    nbrs1 = G.neighbors(node1)\n    # Get neighbors of node 2: nbrs2\n    nbrs2 = G.neighbors(node2)\n\n    # Compute the overlap using set intersections\n    overlap = set(nbrs1).intersection(nbrs2)\n    return overlap\n\ndef kick_similarity(G, kick1, kick2, return_nodes):\n    # Check that the nodes belong to the 'users' partition\n    assert type(kick1) == int\n    assert type(kick2) == int\n\n    # Get the set of nodes shared between the two users\n    shared_nodes = shared_partition_nodes(G, kick1, kick2)\n\n    # Return the fraction of nodes in the projects partition\n    return len(shared_nodes) / len(return_nodes)\n\n\n\ndef kick_similar_users(G, kick1, kick_nodes, return_nodes):\n    # Data checks\n    assert type(kick1) == int\n\n    # Get other nodes from user partition\n    kick_nodes = set(kick_nodes)\n    kick_nodes.remove(kick1)\n\n    # Create the dictionary: similarities\n    similarities = defaultdict(list)\n    for kick2 in kick_nodes:\n        similarity = kick_similarity(G, kick1, kick2, return_nodes)\n        similarities[similarity].append(kick2)\n\n    # Compute maximum similarity score: max_similarity\n    max_similarity = max(similarities.keys())\n\n    # Return list of users that share maximal similarity\n    print(max_similarity)\n    return similarities[max_similarity]","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:39:01.817452Z","iopub.execute_input":"2021-11-28T15:39:01.818483Z","iopub.status.idle":"2021-11-28T15:39:01.827812Z","shell.execute_reply.started":"2021-11-28T15:39:01.818426Z","shell.execute_reply":"2021-11-28T15:39:01.826739Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(kick_similar_users(GDET, 40113, kicker_nodes, returner_nodes))","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:39:12.135886Z","iopub.execute_input":"2021-11-28T15:39:12.136143Z","iopub.status.idle":"2021-11-28T15:39:12.141185Z","shell.execute_reply.started":"2021-11-28T15:39:12.136114Z","shell.execute_reply":"2021-11-28T15:39:12.140362Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"In the directed graph of Team \"ATL\", we want to know which player is the most important player in the Team from graph's view. From graph view we can see the most important player in ATL teams is 37267. We can calculate it using degree of centrality methods. The most important player is the most player that give action in games wheter as kicker or as a receiver.","metadata":{}},{"cell_type":"code","source":"dataATL=playsdataGroup.get_group(\"ATL\")\nGATL = nx.from_pandas_edgelist(dataATL,source='kickerId',target='returnerId', create_using=nx.DiGraph(),edge_attr='specialTeamsPlayType')","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:40:41.119665Z","iopub.execute_input":"2021-11-28T15:40:41.119988Z","iopub.status.idle":"2021-11-28T15:40:41.127748Z","shell.execute_reply.started":"2021-11-28T15:40:41.119957Z","shell.execute_reply":"2021-11-28T15:40:41.126718Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"node_to_neighbors_mapping = [(node, len(list(GATL.neighbors(node)))) for node in GATL.nodes()]\nnode_to_neighbors_mapping","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:40:50.174105Z","iopub.execute_input":"2021-11-28T15:40:50.175044Z","iopub.status.idle":"2021-11-28T15:40:50.184706Z","shell.execute_reply.started":"2021-11-28T15:40:50.175002Z","shell.execute_reply":"2021-11-28T15:40:50.183621Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"node_to_neighbors_ser = pd.Series(data=dict(node_to_neighbors_mapping))\n\nnode_to_neighbors_ser.sort_values(ascending=False).head()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:41:04.275029Z","iopub.execute_input":"2021-11-28T15:41:04.275460Z","iopub.status.idle":"2021-11-28T15:41:04.284003Z","shell.execute_reply.started":"2021-11-28T15:41:04.275429Z","shell.execute_reply":"2021-11-28T15:41:04.282506Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"degCent = nx.degree_centrality(GATL)\nnode_color = ['orange' if type(v)==str else 'green' for v in GATL]\nnode_size =  [v * 10000 for v in degCent.values()]\nplt.figure(figsize=(20,20))\n\n# draw figure with customized options\nnx.draw(GATL, with_labels=True,\n                 node_color=node_color,\n                 node_size=node_size)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:41:12.528915Z","iopub.execute_input":"2021-11-28T15:41:12.529435Z","iopub.status.idle":"2021-11-28T15:41:13.878512Z","shell.execute_reply.started":"2021-11-28T15:41:12.529391Z","shell.execute_reply":"2021-11-28T15:41:13.877748Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Now, we want to construct the graph that representing the Special Teams Play Type with GameId so we can find the most Play Type that have been using in NFL American Football By Special Teams\n","metadata":{}},{"cell_type":"code","source":"#now, we want to construct the graph that representing the Special Teams Play Type with GameId so we can find the most Play Type that have been using in NFL American Football By Special Teams\n\n# Add all columns in the table as edge attribute\nG = nx.from_pandas_edgelist(playsdata, 'gameId', 'specialTeamsPlayType', edge_attr=True )","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:42:20.157730Z","iopub.execute_input":"2021-11-28T15:42:20.158051Z","iopub.status.idle":"2021-11-28T15:42:20.180329Z","shell.execute_reply.started":"2021-11-28T15:42:20.158021Z","shell.execute_reply":"2021-11-28T15:42:20.179123Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Add all columns in the table as edge attribute\nG2 = nx.from_pandas_edgelist(playsdata, 'gameId', 'specialTeamsResult', edge_attr=True )","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:42:38.417334Z","iopub.execute_input":"2021-11-28T15:42:38.417705Z","iopub.status.idle":"2021-11-28T15:42:38.439322Z","shell.execute_reply.started":"2021-11-28T15:42:38.417669Z","shell.execute_reply":"2021-11-28T15:42:38.438458Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"degCent = nx.degree_centrality(G)\nnode_color = ['orange' if type(v)==int else 'green' for v in G]\nnode_size =  [v * 10000 for v in degCent.values()]\nplt.figure(figsize=(20,20))\n\n# draw figure with customized options\nnx.draw(G, with_labels=True,\n                 node_color=node_color,\n                 node_size=node_size)\n\nplt.show()\n\n\n#From the graph below  we can see that the most Play type that have been using by Special Team is \"Kickoff\"","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:42:52.977459Z","iopub.execute_input":"2021-11-28T15:42:52.977959Z","iopub.status.idle":"2021-11-28T15:43:00.029810Z","shell.execute_reply.started":"2021-11-28T15:42:52.977926Z","shell.execute_reply":"2021-11-28T15:43:00.028974Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Besides, we can also construct the graph that representing the Special Teams Result with GameId so we can find the most Special Teams strategie resulted in NFL American Football we can achieve it using degree of centrality\n","metadata":{}},{"cell_type":"code","source":"\ndegCent = nx.degree_centrality(G2)\nnode_color = ['blue' if type(v)==int else 'red' for v in G2]\nnode_size =  [v * 10000 for v in degCent.values()]\nplt.figure(figsize=(20,20))\n\n# draw figure with customized options\nnx.draw(G2, with_labels=True,\n                 node_color=node_color,\n                 node_size=node_size)\n\nplt.show()\n\n\n#From the graph below  we can see that the most Result is \"Return\"","metadata":{"execution":{"iopub.status.busy":"2021-11-28T15:43:30.763363Z","iopub.execute_input":"2021-11-28T15:43:30.763857Z","iopub.status.idle":"2021-11-28T15:43:38.026521Z","shell.execute_reply.started":"2021-11-28T15:43:30.763823Z","shell.execute_reply":"2021-11-28T15:43:38.025559Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"To be continous....","metadata":{}},{"cell_type":"markdown","source":"","metadata":{}}]}