{"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":"import 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\nimport plotly.graph_objects as go\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# load data\n\ngames = pd.read_csv('/kaggle/input/nfl-big-data-bowl-2023/games.csv')\nplayers = pd.read_csv('/kaggle/input/nfl-big-data-bowl-2023/players.csv')\nscouting = pd.read_csv('/kaggle/input/nfl-big-data-bowl-2023/pffScoutingData.csv')\nplays = pd.read_csv('/kaggle/input/nfl-big-data-bowl-2023/plays.csv')\nweek1 = pd.read_csv('/kaggle/input/nfl-big-data-bowl-2023/week1.csv')\nweek2 = pd.read_csv('/kaggle/input/nfl-big-data-bowl-2023/week2.csv')\nweek3 = pd.read_csv('/kaggle/input/nfl-big-data-bowl-2023/week3.csv')\nweek4 = pd.read_csv('/kaggle/input/nfl-big-data-bowl-2023/week4.csv')\nweek5 = pd.read_csv('/kaggle/input/nfl-big-data-bowl-2023/week5.csv')\nweek6 = pd.read_csv('/kaggle/input/nfl-big-data-bowl-2023/week6.csv')\nweek7 = pd.read_csv('/kaggle/input/nfl-big-data-bowl-2023/week7.csv')\nweek8 = pd.read_csv('/kaggle/input/nfl-big-data-bowl-2023/week8.csv')\n\nimport pickle\nwith open('/kaggle/input/rush-dict-5Dec/rush_dict_new.pkl', 'rb') as f:\n    loaded_dict = pickle.load(f)","metadata":{"execution":{"iopub.status.busy":"2022-12-16T21:54:14.883077Z","iopub.execute_input":"2022-12-16T21:54:14.883471Z","iopub.status.idle":"2022-12-16T21:54:36.623215Z","shell.execute_reply.started":"2022-12-16T21:54:14.883372Z","shell.execute_reply":"2022-12-16T21:54:36.621955Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def get_pass_rush(df, playId, gameId):\n    return df.query('playId == '+str(playId)+' & pff_role == \"Pass Rush\" & gameId == '+str(gameId))\n\ndef get_play_data(df, playId, gameId, nflId, early = False):\n    if early == True:\n        return df.query('playId == '+str(playId)+ '& gameId == '+str(gameId)+'& nflId == '+str(nflId)+\"&frameId <=25\")\n    else:\n        return df.query('playId == '+str(playId)+ '& gameId == '+str(gameId)+'& nflId == '+str(nflId))\n    \ndef get_gameIds(df, team):\n    return df.query('homeTeamAbbr==\"'+team+'\" | visitorTeamAbbr==\"'+team+'\"')\n\ndef get_success_rate(df, nflId):\n    network_plays = [df['network'][pair] for pair in  df['network'].keys() if nflId in pair]\n    network_success = [df['network_success'][pair] for pair in  df['network_success'].keys() if nflId in pair]\n    \n    plays = sum(network_plays)\n    success = sum(network_success)\n    \n    return plays, round(success/plays, 2)\n\n\ndef scale_edges(df):\n    max_num = df['network'][max(df['network'], key=df['network'].get)]\n    min_num = df['network'][min(df['network'], key=df['network'].get)]\n    df['network_scaled'] = df['network'].copy()\n    \n    for r_team in df['network_scaled']:\n        scale = (df['network_scaled'][r_team]-min_num)/(max_num-min_num)\n        if scale >0:\n            df['network_scaled'][r_team] = scale\n        else:\n            df['network_scaled'][r_team] = 0.05\n        \n    return df","metadata":{"execution":{"iopub.status.busy":"2022-12-16T21:54:36.625663Z","iopub.execute_input":"2022-12-16T21:54:36.626032Z","iopub.status.idle":"2022-12-16T21:54:36.639869Z","shell.execute_reply.started":"2022-12-16T21:54:36.625985Z","shell.execute_reply":"2022-12-16T21:54:36.638542Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# The Social Network of Pass Rushing\n\nFootball is often referred to as the ultimate team sport, because there are so many moving parts that have to come together to achieve success. Working together as a single unit, whether on offense or defense, requires knowing what your teammates will do without being able to see them. The idea of such a deep relationship with fellow players is often cited as “cohesion” and most often referred to with offensive line play. However, traditional analysis methods struggle to cope with the complex cooperative interactions between individuals in team sports.[1] By transforming the interactions among players into a social network we can analyze the complex interactions using social network analysis.\n\nInvestigating cooperative interaction tendencies between performers is a major theme of research in team sports performance analysis. Many papers have explored applications of social network analysis on sports such handball, soccer, and basketball but few, if any, have explored the application to football. In competitive sport, a team can be characterized as a group of performers who interact in a dynamic way, managing efforts towards achieving common goals, much like a living organism. Even former Defensive Coordinator for the Tampa Bay Buccaneers, Mike Smith, describes the defensive line as more than a single person saying, \"Sometimes everybody thinks pass-rushing is just one player. It's a unit working together up there…”[2] A social network allows us to begin to observe these interactions to identify and characterize the impact a single player has on the entire team.\n\nThe offensive line is not the only position that requires instinctively knowing where your teammates will be at any time. Defensive lines often have equally complex schemes for rushing the passer, regularly employing stunting to try and confuse the offense. I define a stunt as two or more players changing gap responsibilities, which we can observe in player data as two player trajectories crossing in the y-axis. I will limit the trajectories to only the first few seconds of the play when the most deliberate and planned actions are executed.\n\nThe graph below shows a single Tampa Bay pass rushing play using only the players Pro Football Focus has labeled as \"pass rush\". In the graph we can see the defensive linemen working in pairs, with Player4 and Player2 performing one stunt and Player3 and Player0 performing another.  The stunt is identified by the player.  Both pairs of defensive linemen have trajectories crossing early in the play.  Player4’s trajectory crosses Player3 and Player0, but it occurs after the first few seconds of the play so I do not identify Player4 as interacting with Player3 and Player0.\n","metadata":{}},{"cell_type":"code","source":"game_offense = week1.query('gameId == 2021090900 & playId == 97 & team == \"TB\"').dropna()\ngame_defense = week1.query('gameId == 2021090900 & playId == 97 & team == \"DAL\"').dropna()\n#game_defense = game.query('pff_hit != \"NA\"')\n#for frame in game.frameId.unique():\noff = game_offense.query('frameId == 1')\ndefense = game_defense.query('frameId == 1')\n\n# plt.scatter(off.y, off.x)\n# plt.scatter(defense.y, defense.x, color = 'red')\n# plt.show()\n# single_player = game_offense.query('nflId==35634 | nflId == 35481| nflId == 39985 | nflId ==41233| nflId ==44896')\n#ids = scouting.query('gameId == 2021090900 & playId == 97 & pff_role == \"Pass Rush\"')\n\ntrack = game_defense.query('nflId==41263 | nflId == 42403| nflId == 44955 | nflId ==53441| nflId ==53504')\n# plt.scatter(single_player.x, single_player.y, color = 'blue', marker = 'x')\n# plt.scatter(off.x, off.y, color = 'red', marker = 'x' )\nplt.figure(figsize=(12,8))\nplt.scatter(track.x, track.y, color = 'green')\nfor i,player in enumerate(track.nflId.unique()):\n    plt.annotate(\"Player\"+str(i), ((track[track['nflId'] == player].iloc[0].x)+0.2,track[track['nflId'] == player].iloc[0].y))\nplt.title(\"Tampa bay Pass Rush Play\")    \nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-12-16T22:01:20.755094Z","iopub.execute_input":"2022-12-16T22:01:20.755410Z","iopub.status.idle":"2022-12-16T22:01:20.995269Z","shell.execute_reply.started":"2022-12-16T22:01:20.755377Z","shell.execute_reply":"2022-12-16T22:01:20.994690Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{"jupyter":{"source_hidden":true}},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Building the Network\n\nA network consists of two main elements, nodes and edges. In this application each player is represented by a node and two players stunting together will have a line, or edge, connecting their nodes. To build the network I evaluated each defensive play that has players labeled as \"pass rush\" and determine if a stunt was performed. If Player A has a trajectory that crosses Player B and Player C, then Player A will have an edge connecting to both Player B and Player C.\n\nOnce the graph is built we can begin to derive metrics about the social network that exists among pass rushers performing stunting plays. One of the most basic measures of a network is called density or \"cohesion\". Density represents the ratio between the edges present in a graph and the maximum number of edges that could possibly occur in a graph.. In other words, the highest density a graph could have would be an edge connecting each node to every other node in the graph. Translating this concept to a pass rushing network, density would represent the ratio of player pass rushing combinations that are present versus all possible combinations.\n\nIn the graph below I have plotted the pass rushing network for Tampa Bay and Detroit. This representation of the pass rushing network does a poor job bringing forward all the latent information since contained in the graph information since all the nodes and edges are represented equally. We cannot determine if an edge is frequently repeated or which player node has been the most successful. However, there is an obvious difference between the number of connections between players in the two graphs. Tampa Bay has far more connections then Detroit, reflected in a higher density calculation of 0.4 versus Detroit's density of 0.2.\n","metadata":{}},{"cell_type":"code","source":"team_dict = loaded_dict['TB']\n\nTB_rush = nx.Graph()\nfor source, target in team_dict['network']:\n#     print(rush_network[(source,target)])\n    TB_rush.add_edge(source, target)\n    \n\nplt.figure(figsize=(14,8))\nplt.subplot(121)\nplt.title(\"TB Pass Rush Network, Density = 0.4\")\nnx.draw(TB_rush)\n\nteam_dict = loaded_dict['DET']\n\nDET_rush = nx.Graph()\nfor source, target in team_dict['network']:\n    DET_rush.add_edge(source, target)\n    \n\nplt.subplot(122)\nplt.title(\"DET Pass Rush Network, Density = 0.2\")\nnx.draw(DET_rush)","metadata":{"execution":{"iopub.status.busy":"2022-12-16T21:54:36.965322Z","iopub.execute_input":"2022-12-16T21:54:36.965547Z","iopub.status.idle":"2022-12-16T21:54:37.172149Z","shell.execute_reply.started":"2022-12-16T21:54:36.965518Z","shell.execute_reply":"2022-12-16T21:54:37.170953Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"But does a dense network correlate to a higher success rate when rushing the passer? A team could easily follow that train of thinking, believing that a dense network would further confuse the offense because they would never know who was going to stunt. To evaluate this theory I plotted network density versus pressure rate for all NFL teams, where a pressure occurs when a play is marked with either a quarterback hurry, hit, or sack, and also included a trend line to highlight any correlation. The pressure rate is the ration of plays pressure is generated versus all pass rush plays.\n\nIn the chart below we can see that there is actually a clear negative correlation between an increase in graph density and pressure rate. In fact, Houston has the highest network density, close to 0.5, but the lowest pressure rate of all teams. Conversely, Miami had an average network density score of approximately 0.3 yet had the most effective pressure rate of approximately 0.55.\n\n","metadata":{}},{"cell_type":"code","source":"import networkx as nx\n\ndensities = []\ndegree = []\npressure = []\n\nfor team in loaded_dict.keys():\n    team_dict = loaded_dict[team]\n\n    DG = nx.Graph()\n\n    for source, target in team_dict['network']:\n    #     print(rush_network[(source,target)])\n        DG.add_edge(source, target)\n        \n    densities.append(nx.density(DG))\n    pressure.append(team_dict['stunt_pressure']/len(team_dict['stunt_plays']))\n\nplt.figure(figsize=(12,8))\nplt.scatter(densities, pressure)\nfor i, txt in enumerate(loaded_dict.keys()):\n    plt.annotate(txt, (densities[i], pressure[i]))\nplt.ylabel(\"Pressure Rate\")\nplt.title(\"Network Density vs Stunt Pressure Rate\")\nplt.xlabel(\"Network Density\")\n\nb,a = np.polyfit(densities, pressure, deg=1)\nxseq = np.linspace(0.1,.5, num=50)\nplt.plot(xseq, a+b*xseq, color = 'red')\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-12-16T21:54:37.173853Z","iopub.execute_input":"2022-12-16T21:54:37.174164Z","iopub.status.idle":"2022-12-16T21:54:37.439777Z","shell.execute_reply.started":"2022-12-16T21:54:37.174130Z","shell.execute_reply":"2022-12-16T21:54:37.439140Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Improving the Network\n\nThe previous version of the network we displayed was not all that useful, so we should try to make a better one that can provide more insight into the team dynamics.\n\nFirst, I resized each node based on how important we think the player is to the overall pass rush strategy. The degree of a node is how many other nodes it connects to, so if Player A connects to four other players, Player A's node has a degree of four. The number of other connections a player has shows us how often they are involved in stunts so we can view that a sign of importance. Therefore we will resize each player node based on the node's degree, with bigger meaning more important. While we are improving the nodes, let's color them as well based on how successful they are at rushing the passer with a darker color meaning they have been more successful.\n\nNext, we can focus on the connections, or edges, between players. In the previous graph we had no idea how often an edge was repeated, which could be used to understand how strong of a connection there is between a pair of players. To remedy this, we are going to draw thicker connections between players where an edge is repeated frequently.\n\nThe last change we are going to make is the layout. There are many types of layouts that can be used to visualize a network graph, but the previous graph had the nodes so close together it was hard to really see what was happening. Instead of the previous layout, where players were positioned to minimize the distance between nodes, I am going to use a circular layout where all the players are arranged in a circle to better observe the connections.\n\nWith all these changes in hand I am going to replot Detroit's pass rush network, below, and explore some of the insights available. When we first look at Detroit's network we can see that Will Harris and Derrick Barnes have no visible node, which is due to the fact they have only a single connection to another player. Since node size is now tied to a players node connections Will and Derrick have almost no node. We can also see that Alex Anzalone seems to be one of the most important players on the team when it comes to the pass rush. Not only does Alex have the most connections to other players, he also has one of the highest success rates on the team. Alex has a stark contrast with Charles Harris, who has many connections like Alex, but his success rate is much lower.\n\nThe most interesting takeaway from Detroit's network graph might be the cliques that can be observed within the larger network. There are three cliques that stand out from all the other connection: (1) Brockers/Julian Okwara/Bryant, (2) Julian Okwara/Anzalone/Bryant, and (3) Strong/Anzalone/Collins. These cliques are unique in fact there is a strong connection between all the players in the cliques and the cliques exhibit a much higher success rate than other cliques in the graph. The cliques highlighted can be compared with the connections of Trey Flowers, who has a strong connection with Alim McNeil but the success rate of both is quite low.","metadata":{"execution":{"iopub.status.busy":"2022-12-14T02:29:13.856228Z","iopub.execute_input":"2022-12-14T02:29:13.856481Z","iopub.status.idle":"2022-12-14T02:29:13.863520Z","shell.execute_reply.started":"2022-12-14T02:29:13.856451Z","shell.execute_reply":"2022-12-14T02:29:13.862973Z"}}},{"cell_type":"code","source":"team_dict = loaded_dict['DET']\nscale_edges(team_dict)\n\nG = nx.Graph()\nfor source, target in team_dict['network']:\n    G.add_edge(source, target)\n    \nedge_x = []\nedge_y = []\n\npos = nx.circular_layout(G)\nedge_connections = []\n\nfor edge in G.edges():\n    if edge not in team_dict['network']:\n        edge = tuple(reversed(edge))\n        \n    x0, y0 = pos[edge[0]]\n    x1, y1 = pos[edge[1]]\n    \n    suc = team_dict['network_success'][edge]/team_dict['network'][edge]\n#     print(suc, (suc+1)**2.5)\n    edge_trace = go.Scatter(x = [x0,x1,None], \n                            y = [y0,y1,None], \n                            line = dict(width = (suc*1.5)**1.75,\n                                        color = '#888'),\n#                             line = dict(width = (team_dict['network'][edge]**2)/4, color = '#888'),\n                            mode='lines')\n    \n    edge_connections.append(edge_trace)\n\nnode_x = []\nnode_y = []\nt = []\n\nfor node in G.nodes():\n    x, y = pos[node]\n    node_x.append(x)\n    node_y.append(y)\n#     print(node)\n    t.append(players[players['nflId']==node].displayName.iloc[0])\n\n# print(t)\nnode_trace = go.Scatter(x = node_x,\n                        y = node_y,\n                        mode = 'markers+text',\n                        hoverinfo = 'text', \n                        text = t,\n                        marker = dict(size = 10,\n                                     colorscale='ylgnbu',\n                                     color=[],\n                                     colorbar = dict(thickness = 15, \n                                                     title='Success Rate', \n                                                    xanchor = 'left',\n                                                    titleside = 'right'))\n                       )\n\nnode_connections = []\nnode_color = []\nnode_text = []\n\nfor node in G.degree():\n    node_connections.append(node[1]*4)\n    plays, success = get_success_rate(team_dict, node[0])\n    node_color.append(success)\n#     node_text.append(tuple(['<b>'+node+'</b>']))   \n    inter = players[players['nflId']==node[0]]\n    node_text.append(\"Name: \"+inter['displayName'].iloc[0]+\"<br>Connections: \"+str(node[1])+\"<br>Plays: \"+str(plays)+\"<br>Success: \"+str(success))    \n\nnode_trace.marker.size = node_connections\n# node_trace.text = node_text\nnode_trace.marker.color = node_color\n    \nlayout = go.Layout(paper_bgcolor = 'rgba(0,0,0,0)',\n                   plot_bgcolor='rgba(0,0,0,0)',\n                   xaxis = {'showgrid': False, 'zeroline':False},\n                   yaxis = {'showgrid': False, 'zeroline':False},\n                  )\n\nfig = go.Figure(data = [node_trace],\n                layout = layout)\n\nfor trace in edge_connections:\n    fig.add_trace(trace)\n    \nfig.update_layout(showlegend = False)\nfig.update_xaxes(showticklabels = False)\nfig.update_yaxes(showticklabels = False)\nfig.update_traces(textposition = 'top center')\nfig.show()","metadata":{"execution":{"iopub.status.busy":"2022-12-16T21:54:37.441009Z","iopub.execute_input":"2022-12-16T21:54:37.441332Z","iopub.status.idle":"2022-12-16T21:54:37.773658Z","shell.execute_reply.started":"2022-12-16T21:54:37.441301Z","shell.execute_reply":"2022-12-16T21:54:37.771060Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Based on the observations from Detroit's pass rush network we could hypothesize that having a strong connection with other players and connecting with many other nodes are factors in having success while using a stunt on pass rushes. In order to fully explore that idea I plotted the pass rush success rate vs the number of node connections a player has and the number of stunting plays a player was involved with. I also included a regression line on both plots to see if there was a positive or negative trend.\n\nWhen looking at success rate versus the number of stunting plays a player was involved in we can see a slight positive trend that almost looks like it reaches a steady state after 40 plays. This seems to suggest that a player's ability to rush the passer improves the more they do it, but there is a point where improvement stops.\n\nFor the success rate versus node connections there is a slight negative trend in success as the number of connections a player has increases. Also, just like with the previous plot, there appears to almost be a steady state in the graph after around 10 connections. This plot seems to support the previous graph showing a negative correlation between a team's pass rush network density and pass rush success.","metadata":{}},{"cell_type":"code","source":"sr = []\nnumber_of_plays = []\nplayer_degree = []\n\n#get players on team\nfor team in loaded_dict.keys():\n    team_dict = loaded_dict[team]\n\n    G = nx.Graph()\n\n    for source, target in team_dict['network']:\n        G.add_edge(source, target)\n        \n    #get success for each player\n    for nflId in G.degree():\n        plays, success = get_success_rate(team_dict, nflId[0])\n        sr.append(success)\n        number_of_plays.append(plays)\n        player_degree.append(nflId[1])\n\nb,a = np.polyfit(number_of_plays, sr, deg=1)\nxseq = np.linspace(0,80, num=800)\nfig, (ax1,ax2) = plt.subplots(1,2, figsize=(18,8))\nax1.scatter(number_of_plays, sr)\nax1.plot(xseq, a+b*xseq, color = 'red')\nax1.set_title(\"Success Rate vs Number of Stunts\")\nax1.set(xlabel=\"Number of Stunt Plays\", ylabel='Success Rate')\n\nb,a = np.polyfit(player_degree, sr, deg=1)\nxseq = np.linspace(0,14, num=140)\nax2.scatter(player_degree, sr)\nax2.plot(xseq, a+b*xseq, color = 'red')\nax2.set_title(\"Success Rate vs Node Connections\")\nax2.set(xlabel='Number of Connections', ylabel='Success Rate')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2022-12-16T21:54:37.774713Z","iopub.execute_input":"2022-12-16T21:54:37.774967Z","iopub.status.idle":"2022-12-16T21:54:38.074251Z","shell.execute_reply.started":"2022-12-16T21:54:37.774931Z","shell.execute_reply":"2022-12-16T21:54:38.073621Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Conclusions\n\nWhile applying network graphs to explore the complex interactions between players has been explored in many other sports, the NFL is a relatively uncultivated field.  Using network graphs to study player interactions on stunting plays allowed us to see trends at both a macro and micro level.  There is a clear negative correlation between pass rush success and a dense network, implying that a single player interacting with many other players eventually has diminishing returns.  However, a single player interacting with a relatively small number of players was shown to lead to higher success. By studying the graph network of pass rushing interactions a team can determine the most central figure on a defense as well the key relationships that exist. \n\nThere are many other applications for graph networks yet to be explored in football and I hope that this project has stimulated your curiosity. \n","metadata":{}},{"cell_type":"markdown","source":"# References \n\n1. Ribeiro, João, et al. \"Team sports performance analysed through the lens of social network theory: implications for research and practice.\" Sports medicine 47.9 (2017): 1689-1696.\n\n4. https://www.buccaneers.com/news/bucs-d-line-dials-up-heat-through-cohesion","metadata":{}},{"cell_type":"markdown","source":"# Code Appendix","metadata":{"execution":{"iopub.status.busy":"2022-12-13T02:00:52.237046Z","iopub.execute_input":"2022-12-13T02:00:52.237380Z","iopub.status.idle":"2022-12-13T02:00:52.241675Z","shell.execute_reply.started":"2022-12-13T02:00:52.237331Z","shell.execute_reply":"2022-12-13T02:00:52.240881Z"}}},{"cell_type":"code","source":"# # # This code was used to build supporting datasets which were saved after processing. By processing and saving the data off I could\n# # # improve my efficiency of working on the project.  Building the dataset takes around 30 min!\n\n# from collections import defaultdict\n# from itertools import combinations\n# import pickle\n\n# teams = list(games.visitorTeamAbbr.unique() )\n# rush_dict = {team: '' for team in teams}\n# data = [week1,week2, week3, week4, week5, week6, week7, week8]\n# c = 32\n# for team in ['TB']:\n#     rush_network = defaultdict(int)\n#     network_success = defaultdict(int)\n\n#     gameIds = get_gameIds(games, team)\n    \n#     stunt_plays=[]\n#     rush_plays = 0\n#     pressure_plays = 0\n#     stunt_pressure = []\n\n#     for game in gameIds.gameId:\n#         week_indx = [i for i in range(len(data)) if game in data[i].gameId.unique()]\n#         def_plays = plays.query('gameId == '+str(game)+'&defensiveTeam==\"'+team+'\"')\n\n#         for play in def_plays.playId.unique():\n#             #players involved in pass rush on play\n#             pass_rush = get_pass_rush(scouting, play, game)\n#             rush_plays+=1\n            \n#             #count how many pass rush plays generated pressure\n#             if pass_rush.pff_hit.sum()+pass_rush.pff_hurry.sum()+pass_rush.pff_sack.sum()>0:\n#                 pressure_plays+=1\n            \n#             #get all possible player combinations to test for stunts\n#             combos = list(combinations(pass_rush.nflId.unique(),2))\n            \n#             for pair in combos:\n                \n#                 if pair == (40074, 35441):\n#                     print('hi')\n#                 source = get_play_data(data[week_indx[0]], play, game, pair[0], True)\n#                 target = get_play_data(data[week_indx[0]], play, game, pair[1], True)\n                \n#                 #test for stunt\n#                 if len(np.argwhere(np.diff(np.sign(np.array(source['y']) - np.array(target['y'])))).flatten()) > 0:\n#                     #if it is a stunt, count for the network pair and append the play to the list\n#                     print(pair)\n#                     rush_network[(pair[0], pair[1])]+=1\n#                     network_success[(pair[0], pair[1])]+=0\n#                     stunt_plays.append((game,play))\n                    \n#                     #look to see if there was pressure generated on this play\n#                     if pass_rush.pff_hit.sum()+pass_rush.pff_hurry.sum()+pass_rush.pff_sack.sum()>0:\n#                         network_success[(pair[0], pair[1])]+=1\n#                         stunt_pressure.append((game,play))\n                        \n#     stunt_plays = list(set(stunt_plays))  \n#     stunt_pressure = len(list(set(stunt_pressure)))\n#     rush_dict[team] = {\"network\":rush_network}\n#     rush_dict[team].update({'network_success':network_success, \"rush_plays\": rush_plays, \"pressure_plays\":pressure_plays, \"stunt_pressure\":stunt_pressure, \"stunt_plays\":stunt_plays})\n#     c-=1\n#     print(c)\n\n# # with open('rush_dict.pkl', 'wb') as f:\n# #     pickle.dump(rush_dict, f)","metadata":{"execution":{"iopub.status.busy":"2022-12-16T21:54:38.075415Z","iopub.execute_input":"2022-12-16T21:54:38.078128Z","iopub.status.idle":"2022-12-16T21:54:38.083346Z","shell.execute_reply.started":"2022-12-16T21:54:38.078079Z","shell.execute_reply":"2022-12-16T21:54:38.082698Z"},"jupyter":{"source_hidden":true},"trusted":true},"execution_count":null,"outputs":[]}]}