wsba-hockey 1.1.1__py3-none-any.whl → 1.1.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  import pandas as pd
2
2
  import numpy as np
3
- import wsba_main as wsba
3
+ import wsba_hockey as wsba
4
4
  import requests as rs
5
5
  from fastapi import FastAPI
6
6
  from datetime import datetime
@@ -6,7 +6,7 @@ from hockey_rink import NHLRink
6
6
  from hockey_rink import CircularImage
7
7
  from scipy.interpolate import griddata
8
8
  from scipy.ndimage import gaussian_filter
9
- from tools.xg_model import *
9
+ from wsba_hockey.tools.xg_model import *
10
10
 
11
11
  ### PLOTTING FUNCTIONS ###
12
12
  # Provided in this file are basic plotting functions for the WSBA Hockey Python package. #
@@ -6,7 +6,7 @@ import pandas as pd
6
6
  import requests as rs
7
7
  import json as json_lib
8
8
  from bs4 import BeautifulSoup
9
- from tools.utils.shared import *
9
+ from wsba_hockey.tools.utils.shared import *
10
10
  warnings.filterwarnings('ignore')
11
11
 
12
12
  ### SCRAPING FUNCTIONS ###
@@ -4,8 +4,8 @@ import pandas as pd
4
4
  import numpy as np
5
5
  import xgboost as xgb
6
6
  import scipy.sparse as sp
7
- import wsba_main as wsba
8
- import tools.scraping as scraping
7
+ import wsba_hockey.wsba_main as wsba
8
+ import wsba_hockey.tools.scraping as scraping
9
9
  import matplotlib.pyplot as plt
10
10
  from sklearn.calibration import calibration_curve
11
11
  from sklearn.metrics import roc_curve, auc
@@ -118,7 +118,7 @@ def fix_players(pbp):
118
118
 
119
119
  def prep_xG_data(data):
120
120
  #Prep data for xG training and calculation
121
- #data = fix_players(data)
121
+ data = fix_players(data)
122
122
 
123
123
  #Informal groupby
124
124
  data = data.sort_values(by=['season','game_id','period','seconds_elapsed','event_num'])
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wsba_hockey
3
- Version: 1.1.1
3
+ Version: 1.1.3
4
4
  Summary: WeakSide Breakout's complete Python package of access to hockey data, primairly including the scraping of National Hockey League schedule, play-by-play, and shifts information.
5
5
  Author-email: Owen Singh <owenbksingh@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/owensingh38/wsba_hockey/
@@ -2,19 +2,7 @@ wsba_hockey/__init__.py,sha256=yfr8z5PA503iaIQv30ngancwT_WnsuK-tZETKlHcI0M,377
2
2
  wsba_hockey/data_pipelines.py,sha256=wjyxw1ikv4N3kmfTuHxdHj7_W5bz0wAM-DIgxvJVg2s,10852
3
3
  wsba_hockey/workspace.py,sha256=ECScWNqkmx8SDoxTtZYZtM1K1_oX-wQSXXsb_1Bjca4,2014
4
4
  wsba_hockey/wsba_main.py,sha256=c8KEXBpjHHEadMMStMRXsNYqbvtoYdZbmOl8_FBmHQg,53761
5
- wsba_hockey/api/api/index.py,sha256=EgGd5B1382b5OMFkDvKdiodByIaDQY6-mYm58774Y0Y,5924
6
- wsba_hockey/api/api/main.py,sha256=QaObP7kSFr-zjJL549sSWv7LtqHq5mBqvpyjjs2nVn8,87
7
- wsba_hockey/api/api/wsba_main.py,sha256=zrQFsy-AqW1GENm-gOm9VCZNrK4TAINHRadbPi156k8,53757
8
- wsba_hockey/api/api/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- wsba_hockey/api/api/tools/agg.py,sha256=SYZDykUQFygDfRaazlBMKcfs_1eYP7GTJNpUnNKHH-8,21409
10
- wsba_hockey/api/api/tools/plotting.py,sha256=3x59nyqMV6pIoL548m17dfDbc39ZkMTj4EjEdJVG4uo,6017
11
- wsba_hockey/api/api/tools/scraping.py,sha256=i6Br0XCwq4EL1Nq9z9sTzISGQ6kPZ5EYnASVJMD9lyk,45645
12
- wsba_hockey/api/api/tools/xg_model.py,sha256=nOr_2RBijLgPmJ0TTs4wbSsORYmRqWCKRjLKDm7sAhI,18342
13
- wsba_hockey/api/api/tools/archive/old_scraping.py,sha256=hEjMI1RtfeZnf0RBiJFI38oXkLZ3WofeH5xqcF4pzgM,49585
14
- wsba_hockey/api/api/tools/utils/__init__.py,sha256=vccXhOtzARoR99fmEWU1OEI3qCIdQ9Z42AlRA_BUhrs,114
15
- wsba_hockey/api/api/tools/utils/config.py,sha256=D3Uk05-YTyrhfReMTTLfNI3HN_rON2uo_CDE9oER3Lg,351
16
- wsba_hockey/api/api/tools/utils/save_pages.py,sha256=CsyL_0n-b-4pJoUauwU3HpnCO6n69-RlBMJQBd_qGDc,4979
17
- wsba_hockey/api/api/tools/utils/shared.py,sha256=dH_JwZfia5fib8rksy5sW-mBp0pluBPvw37Vdr8Kap0,14211
5
+ wsba_hockey/api/api/index.py,sha256=b2QEOJ72TxOCZT9KsHvIPPow0RwLRCOUyeyrIrSqb6o,5926
18
6
  wsba_hockey/evidence/weakside-breakout/node_modules/duckdb/vendor.py,sha256=lmu0TB0rIYkAuV9-csFJgW-1hJojso_-EZpEoorUUKM,4949
19
7
  wsba_hockey/evidence/weakside-breakout/node_modules/flatted/python/flatted.py,sha256=ke8FuEflns-WlphCcQ9CC0qJqWqX3zEEuak74o6rgE8,3879
20
8
  wsba_hockey/evidence/weakside-breakout/node_modules/flatted/python/test.py,sha256=uTOn6HJd7KeY_PTRvvufv60dmvON3KWp3nnqACj8IlA,2129
@@ -140,16 +128,16 @@ wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/team_heatmaps
140
128
  wsba_hockey/flask/app.py,sha256=J51iA65h9xyJfLgdH0h2sVSbfIR7xgGd2Oy8bJsmpAk,1873
141
129
  wsba_hockey/tools/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
142
130
  wsba_hockey/tools/agg.py,sha256=SYZDykUQFygDfRaazlBMKcfs_1eYP7GTJNpUnNKHH-8,21409
143
- wsba_hockey/tools/plotting.py,sha256=3x59nyqMV6pIoL548m17dfDbc39ZkMTj4EjEdJVG4uo,6017
144
- wsba_hockey/tools/scraping.py,sha256=i6Br0XCwq4EL1Nq9z9sTzISGQ6kPZ5EYnASVJMD9lyk,45645
145
- wsba_hockey/tools/xg_model.py,sha256=t9ETZ8H8VlOiniVscuPTs8b0iXGJS_Ds63FJ1nehlYM,18319
131
+ wsba_hockey/tools/plotting.py,sha256=81hBaM7tcwUNB4-tovPn7QreOUz6B2NuI_SR4-djVSk,6029
132
+ wsba_hockey/tools/scraping.py,sha256=y6vvotniMaGS6-bNg0Vct1gUN3gAsKEy5FLXGkgi1w0,45657
133
+ wsba_hockey/tools/xg_model.py,sha256=nOr_2RBijLgPmJ0TTs4wbSsORYmRqWCKRjLKDm7sAhI,18342
146
134
  wsba_hockey/tools/archive/old_scraping.py,sha256=hEjMI1RtfeZnf0RBiJFI38oXkLZ3WofeH5xqcF4pzgM,49585
147
135
  wsba_hockey/tools/utils/__init__.py,sha256=vccXhOtzARoR99fmEWU1OEI3qCIdQ9Z42AlRA_BUhrs,114
148
136
  wsba_hockey/tools/utils/config.py,sha256=D3Uk05-YTyrhfReMTTLfNI3HN_rON2uo_CDE9oER3Lg,351
149
137
  wsba_hockey/tools/utils/save_pages.py,sha256=CsyL_0n-b-4pJoUauwU3HpnCO6n69-RlBMJQBd_qGDc,4979
150
138
  wsba_hockey/tools/utils/shared.py,sha256=dH_JwZfia5fib8rksy5sW-mBp0pluBPvw37Vdr8Kap0,14211
151
- wsba_hockey-1.1.1.dist-info/licenses/LICENSE,sha256=Nr_Um1Pd5FQJTWWgm7maZArdtYMbDhzXYSwyJIZDGik,1114
152
- wsba_hockey-1.1.1.dist-info/METADATA,sha256=Xb5o3LMbRGCzB1soAZWpFQNIhk_0GnG9e9EQXqqFB-Y,3542
153
- wsba_hockey-1.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
154
- wsba_hockey-1.1.1.dist-info/top_level.txt,sha256=acU7s3x-RZC1zGiqCOmO0g267iqCg34lzIfdmYxxGmQ,12
155
- wsba_hockey-1.1.1.dist-info/RECORD,,
139
+ wsba_hockey-1.1.3.dist-info/licenses/LICENSE,sha256=Nr_Um1Pd5FQJTWWgm7maZArdtYMbDhzXYSwyJIZDGik,1114
140
+ wsba_hockey-1.1.3.dist-info/METADATA,sha256=pGBQxsZfILi46XgUEfLDk3Q5TEadxe3pJNxCDGFZVpk,3542
141
+ wsba_hockey-1.1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
142
+ wsba_hockey-1.1.3.dist-info/top_level.txt,sha256=acU7s3x-RZC1zGiqCOmO0g267iqCg34lzIfdmYxxGmQ,12
143
+ wsba_hockey-1.1.3.dist-info/RECORD,,
@@ -1,4 +0,0 @@
1
- import uvicorn
2
-
3
- if __name__ == "__main__":
4
- uvicorn.run("index:app", reload=True)
File without changes
@@ -1,374 +0,0 @@
1
- import pandas as pd
2
- import numpy as np
3
- from wsba_hockey.tools.xg_model import *
4
-
5
- ## AGGREGATE FUNCTIONS ##
6
-
7
- ## GLOBAL VARIABLES ##
8
- shot_types = ['wrist','deflected','tip-in','slap','backhand','snap','wrap-around','poke','bat','cradle','between-legs']
9
- fenwick_events = ['missed-shot','shot-on-goal','goal']
10
-
11
- def calc_indv(pbp,game_strength,second_group):
12
- # Filter by game strength if not "all"
13
- if game_strength != "all":
14
- pbp = pbp.loc[pbp['strength_state'].isin(game_strength)]
15
-
16
- #Add second event-team column for necessary situations
17
- pbp['event_team_abbr_2'] = np.where(pbp['event_team_abbr'].notna(),
18
- np.where(pbp['event_team_abbr']==pbp['home_team_abbr'],pbp['away_team_abbr'],pbp['home_team_abbr']),np.nan)
19
-
20
- #Change second event team to goal-scoring team for goal events
21
- pbp['event_team_abbr_2'] = np.where(pbp['event_type']=='goal',pbp['event_team_abbr'],pbp['event_team_abbr_2'])
22
-
23
- #Determine how to group
24
- raw_group_1 = ['event_player_1_id','event_team_abbr']+second_group
25
- raw_group_2 = ['event_player_2_id','event_team_abbr_2']+second_group
26
- raw_group_3 = ['event_player_3_id','event_team_abbr']+second_group
27
- clean_group = ['ID','Team','Season']+(['Game'] if 'game_id' in second_group else [])
28
-
29
- #First event player stats
30
- ep1 = (
31
- pbp.loc[pbp['event_type'].isin(["goal", "shot-on-goal", "missed-shot","blocked-shot",'hit','giveaway','takeaway','faceoff','penalty'])].groupby(raw_group_1).agg(
32
- Gi=('event_type', lambda x: (x == "goal").sum()),
33
- Fi=('event_type', lambda x: (x.isin(fenwick_events)).sum()),
34
- Ci=('event_type', lambda x: (x.isin(fenwick_events+['blocked-shot'])).sum()),
35
- xGi=('xG', 'sum'),
36
- HF=('event_type',lambda x: (x=='hit').sum()),
37
- Give=('event_type',lambda x: (x=='giveaway').sum()),
38
- Take=('event_type',lambda x: (x=='takeaway').sum()),
39
- Penl=('event_type',lambda x: (x=='penalty').sum()),
40
- Penl2=('penalty_duration',lambda x: (x==2).sum()),
41
- Penl5=('penalty_duration',lambda x: (x==5).sum()),
42
- PIM=('penalty_duration','sum'),
43
- FW=('event_type',lambda x: (x=='faceoff').sum())
44
- ).reset_index().rename(columns={'event_player_1_id': 'ID', 'event_team_abbr': 'Team', 'season': 'Season', 'game_id':'Game'})
45
- )
46
-
47
- #Second event player stats
48
- ep2 = (
49
- pbp.loc[(pbp['event_type'].isin(['goal','blocked-shot','hit','faceoff','penalty']))&~(pbp['description'].str.lower().str.contains('blocked by teammate',na=False))].groupby(raw_group_2).agg(
50
- A1=('event_type',lambda x: (x=='goal').sum()),
51
- HA=('event_type',lambda x: (x=='hit').sum()),
52
- Draw=('event_type',lambda x: (x=='penalty').sum()),
53
- FL=('event_type',lambda x: (x=='faceoff').sum()),
54
- Block=('event_type',lambda x:(x=='blocked-shot').sum())
55
- ).reset_index().rename(columns={'event_player_2_id': 'ID', 'event_team_abbr_2': 'Team', 'season': 'Season', 'game_id':'Game'})
56
- )
57
-
58
- #Third event player stats
59
- ep3 = (
60
- pbp.loc[pbp['event_type'].isin(["goal"])].groupby(raw_group_3).agg(
61
- A2=('event_type', 'count')
62
- ).reset_index().rename(columns={'event_player_3_id': 'ID', 'event_team_abbr': 'Team', 'season': 'Season', 'game_id':'Game'})
63
- )
64
-
65
- #Rush events
66
- rush = (
67
- pbp.loc[(pbp['event_type'].isin(fenwick_events))&(pbp['rush']>0)].groupby(raw_group_1).agg(
68
- Rush=('event_type','count'),
69
- Rush_G=('event_type',lambda x: (x == 'goal').sum()),
70
- Rush_xG=('xG','sum')
71
- ).reset_index().rename(columns={'event_player_1_id': 'ID', 'event_team_abbr': 'Team', 'season': 'Season', 'game_id':'Game', 'Rush_G': 'Rush G', 'Rush_xG': 'Rush xG'})
72
- )
73
-
74
- indv = pd.merge(ep1,ep2,how='outer',on=clean_group)
75
- indv = pd.merge(indv,ep3,how='outer',on=clean_group)
76
- indv = pd.merge(indv,rush,how='outer',on=clean_group)
77
-
78
- #Shot Types
79
- for type in shot_types:
80
- shot = (
81
- pbp.loc[(pbp['event_type'].isin(["goal", "shot-on-goal", "missed-shot"])&(pbp['shot_type']==type))].groupby(raw_group_1).agg(
82
- Gi=('event_type', lambda x: (x == "goal").sum()),
83
- Fi=('event_type', lambda x: (x != "blocked-shot").sum()),
84
- xGi=('xG', 'sum'),
85
- ).reset_index().rename(columns={'event_player_1_id': 'ID', 'event_team_abbr': 'Team', 'season': 'Season', 'game_id':'Game'})
86
- )
87
-
88
- shot = shot.rename(columns={
89
- 'Gi':f'{type.capitalize()}Gi',
90
- 'Fi':f'{type.capitalize()}Fi',
91
- 'xGi':f'{type.capitalize()}xGi',
92
- })
93
- indv = pd.merge(indv,shot,how='outer',on=clean_group)
94
-
95
- indv[['Gi','A1','A2','Penl','Draw','FW','FL']] = indv[['Gi','A1','A2','Penl','Draw','FW','FL']].fillna(0)
96
-
97
- indv['P1'] = indv['Gi']+indv['A1']
98
- indv['P'] = indv['P1']+indv['A2']
99
- indv['xGi/Fi'] = indv['xGi']/indv['Fi']
100
- indv['Gi/xGi'] = indv['Gi']/indv['xGi']
101
- indv['Fshi%'] = indv['Gi']/indv['Fi']
102
- indv['F'] = indv['FW']+indv['FL']
103
- indv['F%'] = indv['FW']/indv['F']
104
- indv['PM%'] = indv['Take']/(indv['Give']+indv['Take'])
105
- indv['HF%'] = indv['HF']/(indv['HF']+indv['HA'])
106
- indv['PENL%'] = indv['Draw']/(indv['Draw']+indv['Penl'])
107
-
108
- return indv
109
-
110
- def calc_onice(pbp,game_strength,second_group):
111
- #Convert player on-ice columns to vectors
112
- pbp['home_on_ice'] = pbp['home_on_1_id'].astype(str) + ";" + pbp['home_on_2_id'].astype(str) + ";" + pbp['home_on_3_id'].astype(str) + ";" + pbp['home_on_4_id'].astype(str) + ";" + pbp['home_on_5_id'].astype(str) + ";" + pbp['home_on_6_id'].astype(str)
113
- pbp['away_on_ice'] = pbp['away_on_1_id'].astype(str) + ";" + pbp['away_on_2_id'].astype(str) + ";" + pbp['away_on_3_id'].astype(str) + ";" + pbp['away_on_4_id'].astype(str) + ";" + pbp['away_on_5_id'].astype(str) + ";" + pbp['away_on_6_id'].astype(str)
114
-
115
- #Remove NA players
116
- pbp['home_on_ice'] = pbp['home_on_ice'].str.replace(';nan', '', regex=True)
117
- pbp['away_on_ice'] = pbp['away_on_ice'].str.replace(';nan', '', regex=True)
118
-
119
- def process_team_stats(df, on_ice_col, team_col, opp_col, game_strength):
120
- df = df[['season','game_id','strength_state','event_num', team_col, opp_col, 'event_type', 'event_team_venue','event_team_abbr', on_ice_col,'ids_on','shift_type','event_length','zone_code','xG']].copy()
121
-
122
- #Flip strength state (when necessary) and filter by game strength if not "all"
123
- if game_strength != "all":
124
- if game_strength not in ['3v3','4v4','5v5']:
125
- for strength in game_strength:
126
- df['strength_state'] = np.where(np.logical_and(df['event_team_venue']==opp_col[0:4],df['strength_state']==strength[::-1]),strength,df['strength_state'])
127
-
128
- df = df.loc[df['strength_state'].isin(game_strength)]
129
-
130
- df[on_ice_col] = df[on_ice_col].str.split(';')
131
- df = df.explode(on_ice_col)
132
- df = df.rename(columns={on_ice_col: 'ID', 'season': 'Season'})
133
- df['xGF'] = np.where(df['event_team_abbr'] == df[team_col], df['xG'], 0)
134
- df['xGA'] = np.where(df['event_team_abbr'] == df[opp_col], df['xG'], 0)
135
- df['GF'] = np.where((df['event_type'] == "goal") & (df['event_team_abbr'] == df[team_col]), 1, 0)
136
- df['GA'] = np.where((df['event_type'] == "goal") & (df['event_team_abbr'] == df[opp_col]), 1, 0)
137
- df['FF'] = np.where((df['event_type'].isin(fenwick_events)) & (df['event_team_abbr'] == df[team_col]), 1, 0)
138
- df['FA'] = np.where((df['event_type'].isin(fenwick_events)) & (df['event_team_abbr'] == df[opp_col]), 1, 0)
139
- df['CF'] = np.where((df['event_type'].isin(fenwick_events+['blocked-shot'])) & (df['event_team_abbr'] == df[team_col]), 1, 0)
140
- df['CA'] = np.where((df['event_type'].isin(fenwick_events+['blocked-shot'])) & (df['event_team_abbr'] == df[opp_col]), 1, 0)
141
- df['OZF'] = np.where((df['event_type']=='faceoff') & ((df['zone_code']=='O')&((df['event_team_abbr'] == df[team_col])) | (df['zone_code']=='D')&((df['event_team_abbr'] == df[opp_col]))), 1, 0)
142
- df['NZF'] = np.where((df['zone_code']=='N') & (df['event_team_abbr']==df[team_col]),1,0)
143
- df['DZF'] = np.where((df['event_type']=='faceoff') & ((df['zone_code']=='D')&((df['event_team_abbr'] == df[team_col])) | (df['zone_code']=='O')&((df['event_team_abbr'] == df[opp_col]))), 1, 0)
144
-
145
- stats = df.groupby(['ID',team_col,'Season']+(['game_id'] if 'game_id' in second_group else [])).agg(
146
- GP=('game_id','nunique'),
147
- TOI=('event_length','sum'),
148
- FF=('FF', 'sum'),
149
- FA=('FA', 'sum'),
150
- GF=('GF', 'sum'),
151
- GA=('GA', 'sum'),
152
- xGF=('xGF', 'sum'),
153
- xGA=('xGA', 'sum'),
154
- CF=('CF','sum'),
155
- CA=('CA','sum'),
156
- OZF=('OZF','sum'),
157
- NZF=('NZF','sum'),
158
- DZF=('DZF','sum')
159
- ).reset_index()
160
-
161
- return stats.rename(columns={team_col:"Team", 'game_id':'Game'})
162
-
163
- home_stats = process_team_stats(pbp, 'home_on_ice', 'home_team_abbr', 'away_team_abbr',game_strength)
164
- away_stats = process_team_stats(pbp, 'away_on_ice', 'away_team_abbr', 'home_team_abbr',game_strength)
165
-
166
- onice_stats = pd.concat([home_stats,away_stats]).groupby(['ID','Team','Season']+(['Game'] if 'game_id' in second_group else [])).agg(
167
- GP=('GP','sum'),
168
- TOI=('TOI','sum'),
169
- FF=('FF', 'sum'),
170
- FA=('FA', 'sum'),
171
- GF=('GF', 'sum'),
172
- GA=('GA', 'sum'),
173
- xGF=('xGF', 'sum'),
174
- xGA=('xGA', 'sum'),
175
- CF=('CF','sum'),
176
- CA=('CA','sum'),
177
- OZF=('OZF','sum'),
178
- NZF=('NZF','sum'),
179
- DZF=('DZF','sum')
180
- ).reset_index()
181
-
182
- onice_stats['xGF/FF'] = onice_stats['xGF']/onice_stats['FF']
183
- onice_stats['GF/xGF'] = onice_stats['GF']/onice_stats['xGF']
184
- onice_stats['FshF%'] = onice_stats['GF']/onice_stats['FF']
185
- onice_stats['xGA/FA'] = onice_stats['xGA']/onice_stats['FA']
186
- onice_stats['GA/xGA'] = onice_stats['GA']/onice_stats['xGA']
187
- onice_stats['FshA%'] = onice_stats['GA']/onice_stats['FA']
188
- onice_stats['OZF%'] = onice_stats['OZF']/(onice_stats['OZF']+onice_stats['NZF']+onice_stats['DZF'])
189
- onice_stats['NZF%'] = onice_stats['NZF']/(onice_stats['OZF']+onice_stats['NZF']+onice_stats['DZF'])
190
- onice_stats['DZF%'] = onice_stats['DZF']/(onice_stats['OZF']+onice_stats['NZF']+onice_stats['DZF'])
191
-
192
- return onice_stats
193
-
194
- def calc_team(pbp,game_strength,second_group):
195
- teams = []
196
- for team in [('away','home'),('home','away')]:
197
- #Flip strength state (when necessary) and filter by game strength if not "all"
198
- if game_strength != "all":
199
- if game_strength not in ['3v3','4v4','5v5']:
200
- for strength in game_strength:
201
- pbp['strength_state'] = np.where(np.logical_and(pbp['event_team_venue']==team[1],pbp['strength_state']==strength[::-1]),strength,pbp['strength_state'])
202
-
203
- pbp = pbp.loc[pbp['strength_state'].isin(game_strength)]
204
-
205
- pbp['xGF'] = np.where(pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr'], pbp['xG'], 0)
206
- pbp['xGA'] = np.where(pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr'], pbp['xG'], 0)
207
- pbp['GF'] = np.where((pbp['event_type'] == "goal") & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
208
- pbp['GA'] = np.where((pbp['event_type'] == "goal") & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr']), 1, 0)
209
- pbp['FF'] = np.where((pbp['event_type'].isin(fenwick_events)) & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
210
- pbp['FA'] = np.where((pbp['event_type'].isin(fenwick_events)) & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr']), 1, 0)
211
- pbp['CF'] = np.where((pbp['event_type'].isin(fenwick_events+['blocked-shot'])) & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
212
- pbp['CA'] = np.where((pbp['event_type'].isin(fenwick_events+['blocked-shot'])) & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr']), 1, 0)
213
- pbp['HF'] = np.where((pbp['event_type']=='hit') & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
214
- pbp['HA'] = np.where((pbp['event_type']=='hit') & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr']), 1, 0)
215
- pbp['Penl'] = np.where((pbp['event_type']=='penalty') & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
216
- pbp['Penl2'] = np.where((pbp['event_type']=='penalty') & (pbp['penalty_duration']==2) & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
217
- pbp['Penl5'] = np.where((pbp['event_type']=='penalty') & (pbp['penalty_duration']==5) & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
218
- pbp['PIM'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), pbp['penalty_duration'], 0)
219
- pbp['Draw'] = np.where((pbp['event_type']=='penalty') & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr']), 1, 0)
220
- pbp['Give'] = np.where((pbp['event_type']=='giveaway') & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
221
- pbp['Take'] = np.where((pbp['event_type']=='takeaway') & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
222
- pbp['Block'] = pbp['CA'] - pbp['FA']
223
- pbp['RushF'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr'])&(pbp['rush']>0), 1, 0)
224
- pbp['RushA'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr'])&(pbp['rush']>0), 1, 0)
225
- pbp['RushFxG'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr'])&(pbp['rush']>0), pbp['xG'], 0)
226
- pbp['RushAxG'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr'])&(pbp['rush']>0), pbp['xG'], 0)
227
- pbp['RushFG'] = np.where((pbp['event_type'] == "goal") & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr'])&(pbp['rush']>0), 1, 0)
228
- pbp['RushAG'] = np.where((pbp['event_type'] == "goal") & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr'])&(pbp['rush']>0), 1, 0)
229
-
230
- stats = pbp.groupby([f'{team[0]}_team_abbr']+second_group).agg(
231
- GP=('game_id','nunique'),
232
- TOI=('event_length','sum'),
233
- FF=('FF', 'sum'),
234
- FA=('FA', 'sum'),
235
- GF=('GF', 'sum'),
236
- GA=('GA', 'sum'),
237
- xGF=('xGF', 'sum'),
238
- xGA=('xGA', 'sum'),
239
- CF=('CF','sum'),
240
- CA=('CA','sum'),
241
- HF=('HF','sum'),
242
- HA=('HA','sum'),
243
- Penl=('Penl','sum'),
244
- Penl2=('Penl2','sum'),
245
- Penl5=('Penl5','sum'),
246
- PIM=('PIM','sum'),
247
- Draw=('Draw','sum'),
248
- Give=('Give','sum'),
249
- Take=('Take','sum'),
250
- Block=('Block','sum'),
251
- RushF=('RushF','sum'),
252
- RushA=('RushA','sum'),
253
- RushFxG=('RushFxG','sum'),
254
- RushAxG=('RushAxG','sum'),
255
- RushFG=('RushFG','sum'),
256
- RushAG=('RushAG','sum'),
257
- ).reset_index().rename(columns={f'{team[0]}_team_abbr':"Team",'season':"Season",'game_id':'Game'})
258
- teams.append(stats)
259
-
260
- onice_stats = pd.concat(teams).groupby(['Team','Season']+(['Game'] if 'game_id' in second_group else [])).agg(
261
- GP=('GP','sum'),
262
- TOI=('TOI','sum'),
263
- FF=('FF', 'sum'),
264
- FA=('FA', 'sum'),
265
- GF=('GF', 'sum'),
266
- GA=('GA', 'sum'),
267
- xGF=('xGF', 'sum'),
268
- xGA=('xGA', 'sum'),
269
- CF=('CF','sum'),
270
- CA=('CA','sum'),
271
- HF=('HF','sum'),
272
- HA=('HA','sum'),
273
- Penl=('Penl','sum'),
274
- Penl2=('Penl2','sum'),
275
- Penl5=('Penl5','sum'),
276
- PIM=('PIM','sum'),
277
- Draw=('Draw','sum'),
278
- Give=('Give','sum'),
279
- Take=('Take','sum'),
280
- Block=('Block','sum'),
281
- RushF=('RushF','sum'),
282
- RushA=('RushA','sum'),
283
- RushFxG=('RushFxG','sum'),
284
- RushAxG=('RushAxG','sum'),
285
- RushFG=('RushFG','sum'),
286
- RushAG=('RushAG','sum'),
287
- ).reset_index()
288
-
289
- onice_stats['xGF/FF'] = onice_stats['xGF']/onice_stats['FF']
290
- onice_stats['GF/xGF'] = onice_stats['GF']/onice_stats['xGF']
291
- onice_stats['FshF%'] = onice_stats['GF']/onice_stats['FF']
292
- onice_stats['xGA/FA'] = onice_stats['xGA']/onice_stats['FA']
293
- onice_stats['GA/xGA'] = onice_stats['GA']/onice_stats['xGA']
294
- onice_stats['FshA%'] = onice_stats['GA']/onice_stats['FA']
295
- onice_stats['PM%'] = onice_stats['Take']/(onice_stats['Give']+onice_stats['Take'])
296
- onice_stats['HF%'] = onice_stats['HF']/(onice_stats['HF']+onice_stats['HA'])
297
- onice_stats['PENL%'] = onice_stats['Draw']/(onice_stats['Draw']+onice_stats['Penl'])
298
-
299
- return onice_stats
300
-
301
- def calc_goalie(pbp,game_strength,second_group):
302
- teams=[]
303
- for team in [('away','home'),('home','away')]:
304
- #Flip strength state (when necessary) and filter by game strength if not "all"
305
- if game_strength != "all":
306
- if game_strength not in ['3v3','4v4','5v5']:
307
- for strength in game_strength:
308
- pbp['strength_state'] = np.where(np.logical_and(pbp['event_team_venue']==team[1],pbp['strength_state']==strength[::-1]),strength,pbp['strength_state'])
309
-
310
- pbp = pbp.loc[pbp['strength_state'].isin(game_strength)]
311
-
312
- pbp['xGF'] = np.where(pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr'], pbp['xG'], 0)
313
- pbp['xGA'] = np.where(pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr'], pbp['xG'], 0)
314
- pbp['GF'] = np.where((pbp['event_type'] == "goal") & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
315
- pbp['GA'] = np.where((pbp['event_type'] == "goal") & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr']), 1, 0)
316
- pbp['FF'] = np.where((pbp['event_type'].isin(fenwick_events)) & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
317
- pbp['FA'] = np.where((pbp['event_type'].isin(fenwick_events)) & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr']), 1, 0)
318
- pbp['CF'] = np.where((pbp['event_type'].isin(fenwick_events+['blocked-shot'])) & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
319
- pbp['CA'] = np.where((pbp['event_type'].isin(fenwick_events+['blocked-shot'])) & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr']), 1, 0)
320
- pbp['RushF'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr'])&(pbp['rush']>0), 1, 0)
321
- pbp['RushA'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr'])&(pbp['rush']>0), 1, 0)
322
- pbp['RushFxG'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr'])&(pbp['rush']>0), pbp['xG'], 0)
323
- pbp['RushAxG'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr'])&(pbp['rush']>0), pbp['xG'], 0)
324
- pbp['RushFG'] = np.where((pbp['event_type'] == "goal") & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr'])&(pbp['rush']>0), 1, 0)
325
- pbp['RushAG'] = np.where((pbp['event_type'] == "goal") & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr'])&(pbp['rush']>0), 1, 0)
326
-
327
- stats = pbp.groupby([f'{team[0]}_goalie_id',f'{team[0]}_team_abbr']+second_group).agg(
328
- GP=('game_id','nunique'),
329
- TOI=('event_length','sum'),
330
- FF=('FF', 'sum'),
331
- FA=('FA', 'sum'),
332
- GF=('GF', 'sum'),
333
- GA=('GA', 'sum'),
334
- xGF=('xGF', 'sum'),
335
- xGA=('xGA', 'sum'),
336
- CF=('CF','sum'),
337
- CA=('CA','sum'),
338
- RushF=('RushF','sum'),
339
- RushA=('RushA','sum'),
340
- RushFxG=('RushFxG','sum'),
341
- RushAxG=('RushAxG','sum'),
342
- RushFG=('RushFG','sum'),
343
- RushAG=('RushAG','sum'),
344
- ).reset_index().rename(columns={f'{team[0]}_goalie_id':"ID",f'{team[0]}_team_abbr':"Team",'season':"Season",'game_id':'Game'})
345
- teams.append(stats)
346
-
347
- onice_stats = pd.concat(teams).groupby(['ID','Team','Season']+(['Game'] if 'game_id' in second_group else [])).agg(
348
- GP=('GP','sum'),
349
- TOI=('TOI','sum'),
350
- FF=('FF', 'sum'),
351
- FA=('FA', 'sum'),
352
- GF=('GF', 'sum'),
353
- GA=('GA', 'sum'),
354
- xGF=('xGF', 'sum'),
355
- xGA=('xGA', 'sum'),
356
- CF=('CF','sum'),
357
- CA=('CA','sum'),
358
- RushF=('RushF','sum'),
359
- RushA=('RushA','sum'),
360
- RushFxG=('RushFxG','sum'),
361
- RushAxG=('RushAxG','sum'),
362
- RushFG=('RushFG','sum'),
363
- RushAG=('RushAG','sum'),
364
- ).reset_index()
365
-
366
- onice_stats['xGF/FF'] = onice_stats['xGF']/onice_stats['FF']
367
- onice_stats['GF/xGF'] = onice_stats['GF']/onice_stats['xGF']
368
- onice_stats['FshF%'] = onice_stats['GF']/onice_stats['FF']
369
- onice_stats['xGA/FA'] = onice_stats['xGA']/onice_stats['FA']
370
- onice_stats['GA/xGA'] = onice_stats['GA']/onice_stats['xGA']
371
- onice_stats['FshA%'] = onice_stats['GA']/onice_stats['FA']
372
- onice_stats['GSAx'] = onice_stats['xGA']-onice_stats['GA']
373
-
374
- return onice_stats