wsba-hockey 1.0.3__py3-none-any.whl → 1.0.4__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.
Files changed (130) hide show
  1. wsba_hockey/data_pipelines.py +183 -0
  2. wsba_hockey/evidence/weakside-breakout/node_modules/duckdb/vendor.py +146 -0
  3. wsba_hockey/evidence/weakside-breakout/node_modules/flatted/python/flatted.py +149 -0
  4. wsba_hockey/evidence/weakside-breakout/node_modules/flatted/python/test.py +63 -0
  5. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/gyp_main.py +45 -0
  6. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py +367 -0
  7. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py +206 -0
  8. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py +1270 -0
  9. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py +1547 -0
  10. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py +59 -0
  11. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py +153 -0
  12. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py +271 -0
  13. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py +574 -0
  14. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/__init__.py +690 -0
  15. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/common.py +661 -0
  16. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/common_test.py +78 -0
  17. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py +165 -0
  18. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py +109 -0
  19. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py +55 -0
  20. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/__init__.py +0 -0
  21. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py +808 -0
  22. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py +1173 -0
  23. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py +1321 -0
  24. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py +120 -0
  25. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py +103 -0
  26. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py +464 -0
  27. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py +89 -0
  28. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py +58 -0
  29. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py +2714 -0
  30. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py +3981 -0
  31. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py +44 -0
  32. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py +2936 -0
  33. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py +55 -0
  34. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py +1394 -0
  35. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py +25 -0
  36. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/input.py +3130 -0
  37. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/input_test.py +98 -0
  38. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py +771 -0
  39. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py +1271 -0
  40. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py +174 -0
  41. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py +61 -0
  42. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py +374 -0
  43. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py +1939 -0
  44. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py +302 -0
  45. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py +3197 -0
  46. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py +65 -0
  47. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/test_gyp.py +261 -0
  48. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/graphviz.py +102 -0
  49. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/pretty_gyp.py +156 -0
  50. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/pretty_sln.py +181 -0
  51. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/gyp/tools/pretty_vcproj.py +339 -0
  52. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/test/fixtures/test-charmap.py +31 -0
  53. wsba_hockey/evidence/weakside-breakout/node_modules/node-gyp/update-gyp.py +64 -0
  54. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/gyp_main.py +45 -0
  55. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSNew.py +367 -0
  56. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSProject.py +206 -0
  57. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings.py +1270 -0
  58. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSSettings_test.py +1547 -0
  59. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSToolFile.py +59 -0
  60. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSUserFile.py +153 -0
  61. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSUtil.py +271 -0
  62. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/MSVSVersion.py +574 -0
  63. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/__init__.py +666 -0
  64. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/common.py +654 -0
  65. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/common_test.py +78 -0
  66. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/easy_xml.py +165 -0
  67. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/easy_xml_test.py +109 -0
  68. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/flock_tool.py +55 -0
  69. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/__init__.py +0 -0
  70. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/analyzer.py +808 -0
  71. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/android.py +1173 -0
  72. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/cmake.py +1321 -0
  73. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/compile_commands_json.py +120 -0
  74. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/dump_dependency_json.py +103 -0
  75. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/eclipse.py +464 -0
  76. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/gypd.py +89 -0
  77. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/gypsh.py +58 -0
  78. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/make.py +2518 -0
  79. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs.py +3978 -0
  80. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/msvs_test.py +44 -0
  81. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja.py +2936 -0
  82. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/ninja_test.py +55 -0
  83. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode.py +1394 -0
  84. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/generator/xcode_test.py +25 -0
  85. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/input.py +3137 -0
  86. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/input_test.py +98 -0
  87. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/mac_tool.py +771 -0
  88. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/msvs_emulation.py +1271 -0
  89. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/ninja_syntax.py +174 -0
  90. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/simple_copy.py +61 -0
  91. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/win_tool.py +374 -0
  92. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xcode_emulation.py +1939 -0
  93. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xcode_ninja.py +302 -0
  94. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xcodeproj_file.py +3197 -0
  95. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/pylib/gyp/xml_fix.py +65 -0
  96. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/setup.py +42 -0
  97. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/test_gyp.py +260 -0
  98. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/graphviz.py +102 -0
  99. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_gyp.py +156 -0
  100. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_sln.py +181 -0
  101. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/gyp/tools/pretty_vcproj.py +339 -0
  102. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/test/fixtures/test-charmap.py +31 -0
  103. wsba_hockey/evidence/weakside-breakout/node_modules/sqlite3/node_modules/node-gyp/update-gyp.py +46 -0
  104. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/game_stats/app.py +401 -0
  105. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/game_stats/name_fix.py +47 -0
  106. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/app.py +108 -0
  107. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/plot.py +93 -0
  108. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/heatmaps/rink_plot.py +245 -0
  109. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/app.py +145 -0
  110. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/plot.py +77 -0
  111. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/matchups/rink_plot.py +245 -0
  112. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/app.py +389 -0
  113. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/plot.py +70 -0
  114. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/pbp/rink_plot.py +245 -0
  115. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/app.py +110 -0
  116. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/plot.py +58 -0
  117. wsba_hockey/evidence/weakside-breakout/wsba_nhl_apps/wsba_nhl_apps/skater/rink_plot.py +245 -0
  118. wsba_hockey/tools/agg.py +242 -53
  119. wsba_hockey/tools/plotting.py +12 -17
  120. wsba_hockey/tools/scraping.py +149 -258
  121. wsba_hockey/tools/xg_model.py +357 -311
  122. wsba_hockey/workspace.py +22 -117
  123. wsba_hockey/wsba_main.py +493 -165
  124. {wsba_hockey-1.0.3.dist-info → wsba_hockey-1.0.4.dist-info}/METADATA +1 -1
  125. wsba_hockey-1.0.4.dist-info/RECORD +135 -0
  126. {wsba_hockey-1.0.3.dist-info → wsba_hockey-1.0.4.dist-info}/WHEEL +1 -1
  127. wsba_hockey/stats/calculate_viz/shot_impact.py +0 -2
  128. wsba_hockey-1.0.3.dist-info/RECORD +0 -19
  129. {wsba_hockey-1.0.3.dist-info → wsba_hockey-1.0.4.dist-info}/licenses/LICENSE +0 -0
  130. {wsba_hockey-1.0.3.dist-info → wsba_hockey-1.0.4.dist-info}/top_level.txt +0 -0
wsba_hockey/tools/agg.py CHANGED
@@ -8,46 +8,81 @@ from .xg_model import *
8
8
  shot_types = ['wrist','deflected','tip-in','slap','backhand','snap','wrap-around','poke','bat','cradle','between-legs']
9
9
  fenwick_events = ['missed-shot','shot-on-goal','goal']
10
10
 
11
- def calc_indv(pbp):
12
- indv = (
13
- pbp.loc[pbp['event_type'].isin(["goal", "shot-on-goal", "missed-shot"])].groupby(['event_player_1_id','event_team_abbr','season']).agg(
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(
14
32
  Gi=('event_type', lambda x: (x == "goal").sum()),
15
- Fi=('event_type', lambda x: (x != "blocked-shot").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()),
16
35
  xGi=('xG', 'sum'),
17
- Rush=('rush_mod',lambda x: (x > 0).sum())
18
- ).reset_index().rename(columns={'event_player_1_id': 'ID', 'event_team_abbr': 'Team', 'season': 'Season'})
19
- )
20
-
21
- rush_xg = (
22
- pbp.loc[(pbp['event_type'].isin(["goal", "shot-on-goal", "missed-shot"]))&(pbp['rush_mod']>0)].groupby(['event_player_1_id','event_team_abbr','season']).agg(
23
- Rush_G=('event_type', lambda x:(x == 'goal').sum()),
24
- Rush_xG=('xG','sum')
25
- ).reset_index().rename(columns={'event_player_1_id': 'ID', 'event_team_abbr': 'Team', 'season': 'Season', 'Rush_G':'Rush G','Rush_xG':'Rush xG'})
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'})
26
45
  )
27
46
 
28
- a1 = (
29
- pbp.loc[pbp['event_type'].isin(["goal"])].groupby(['event_player_2_id', 'event_team_abbr','season']).agg(
30
- A1=('event_type','count')
31
- ).reset_index().rename(columns={'event_player_2_id': 'ID', 'event_team_abbr': 'Team', 'season': 'Season'})
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'})
32
56
  )
33
57
 
34
- a2 = (
35
- pbp.loc[pbp['event_type'].isin(["goal"])].groupby(['event_player_3_id', 'event_team_abbr', 'season']).agg(
36
- A2=('event_type','count')
37
- ).reset_index().rename(columns={'event_player_3_id': 'ID', 'event_team_abbr': 'Team', 'season': 'Season'})
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'})
38
72
  )
39
- indv = pd.merge(indv,rush_xg,how='outer',on=['ID','Team','Season'])
40
- indv = pd.merge(indv,a1,how='outer',on=['ID','Team','Season'])
41
- indv = pd.merge(indv,a2,how='outer',on=['ID','Team','Season'])
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)
42
77
 
43
78
  #Shot Types
44
79
  for type in shot_types:
45
80
  shot = (
46
- pbp.loc[(pbp['event_type'].isin(["goal", "shot-on-goal", "missed-shot"])&(pbp['shot_type']==type))].groupby(['event_player_1_id', 'event_team_abbr', 'season']).agg(
81
+ pbp.loc[(pbp['event_type'].isin(["goal", "shot-on-goal", "missed-shot"])&(pbp['shot_type']==type))].groupby(raw_group_1).agg(
47
82
  Gi=('event_type', lambda x: (x == "goal").sum()),
48
83
  Fi=('event_type', lambda x: (x != "blocked-shot").sum()),
49
84
  xGi=('xG', 'sum'),
50
- ).reset_index().rename(columns={'event_player_1_id': 'ID', 'event_team_abbr': 'Team', 'season': 'Season'})
85
+ ).reset_index().rename(columns={'event_player_1_id': 'ID', 'event_team_abbr': 'Team', 'season': 'Season', 'game_id':'Game'})
51
86
  )
52
87
 
53
88
  shot = shot.rename(columns={
@@ -55,29 +90,43 @@ def calc_indv(pbp):
55
90
  'Fi':f'{type.capitalize()}Fi',
56
91
  'xGi':f'{type.capitalize()}xGi',
57
92
  })
58
- indv = pd.merge(indv,shot,how='outer',on=['ID','Team','Season'])
93
+ indv = pd.merge(indv,shot,how='outer',on=clean_group)
59
94
 
60
- indv[['Gi','A1','A2']] = indv[['Gi','A1','A2']].fillna(0)
95
+ indv[['Gi','A1','A2','Penl','Draw','FW','FL']] = indv[['Gi','A1','A2','Penl','Draw','FW','FL']].fillna(0)
61
96
 
62
97
  indv['P1'] = indv['Gi']+indv['A1']
63
98
  indv['P'] = indv['P1']+indv['A2']
64
99
  indv['xGi/Fi'] = indv['xGi']/indv['Fi']
65
100
  indv['Gi/xGi'] = indv['Gi']/indv['xGi']
66
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'])
67
107
 
68
108
  return indv
69
109
 
70
- def calc_onice(pbp):
71
- # Convert player on-ice columns to vectors
110
+ def calc_onice(pbp,game_strength,second_group):
111
+ #Convert player on-ice columns to vectors
72
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)
73
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)
74
114
 
75
- # Remove NA players
115
+ #Remove NA players
76
116
  pbp['home_on_ice'] = pbp['home_on_ice'].str.replace(';nan', '', regex=True)
77
117
  pbp['away_on_ice'] = pbp['away_on_ice'].str.replace(';nan', '', regex=True)
78
-
79
- def process_team_stats(df, on_ice_col, team_col, opp_col):
80
- df = df[['season','game_id', 'event_num', team_col, opp_col, 'event_type', 'event_team_abbr', on_ice_col,'event_length','xG']].copy()
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
+
81
130
  df[on_ice_col] = df[on_ice_col].str.split(';')
82
131
  df = df.explode(on_ice_col)
83
132
  df = df.rename(columns={on_ice_col: 'ID', 'season': 'Season'})
@@ -87,8 +136,13 @@ def calc_onice(pbp):
87
136
  df['GA'] = np.where((df['event_type'] == "goal") & (df['event_team_abbr'] == df[opp_col]), 1, 0)
88
137
  df['FF'] = np.where((df['event_type'].isin(fenwick_events)) & (df['event_team_abbr'] == df[team_col]), 1, 0)
89
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)
90
144
 
91
- stats = df.groupby(['ID',team_col,'Season']).agg(
145
+ stats = df.groupby(['ID',team_col,'Season']+(['game_id'] if 'game_id' in second_group else [])).agg(
92
146
  GP=('game_id','nunique'),
93
147
  TOI=('event_length','sum'),
94
148
  FF=('FF', 'sum'),
@@ -96,15 +150,20 @@ def calc_onice(pbp):
96
150
  GF=('GF', 'sum'),
97
151
  GA=('GA', 'sum'),
98
152
  xGF=('xGF', 'sum'),
99
- xGA=('xGA', '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')
100
159
  ).reset_index()
101
160
 
102
- return stats.rename(columns={team_col:"Team"})
161
+ return stats.rename(columns={team_col:"Team", 'game_id':'Game'})
103
162
 
104
- home_stats = process_team_stats(pbp, 'home_on_ice', 'home_team_abbr', 'away_team_abbr')
105
- away_stats = process_team_stats(pbp, 'away_on_ice', 'away_team_abbr', 'home_team_abbr')
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)
106
165
 
107
- onice_stats = pd.concat([home_stats,away_stats]).groupby(['ID','Team','Season']).agg(
166
+ onice_stats = pd.concat([home_stats,away_stats]).groupby(['ID','Team','Season']+(['Game'] if 'game_id' in second_group else [])).agg(
108
167
  GP=('GP','sum'),
109
168
  TOI=('TOI','sum'),
110
169
  FF=('FF', 'sum'),
@@ -112,7 +171,12 @@ def calc_onice(pbp):
112
171
  GF=('GF', 'sum'),
113
172
  GA=('GA', 'sum'),
114
173
  xGF=('xGF', 'sum'),
115
- xGA=('xGA', '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')
116
180
  ).reset_index()
117
181
 
118
182
  onice_stats['xGF/FF'] = onice_stats['xGF']/onice_stats['FF']
@@ -121,26 +185,49 @@ def calc_onice(pbp):
121
185
  onice_stats['xGA/FA'] = onice_stats['xGA']/onice_stats['FA']
122
186
  onice_stats['GA/xGA'] = onice_stats['GA']/onice_stats['xGA']
123
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'])
124
191
 
125
192
  return onice_stats
126
193
 
127
- def calc_team(pbp):
194
+ def calc_team(pbp,game_strength,second_group):
128
195
  teams = []
129
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
+
130
205
  pbp['xGF'] = np.where(pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr'], pbp['xG'], 0)
131
206
  pbp['xGA'] = np.where(pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr'], pbp['xG'], 0)
132
207
  pbp['GF'] = np.where((pbp['event_type'] == "goal") & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
133
208
  pbp['GA'] = np.where((pbp['event_type'] == "goal") & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr']), 1, 0)
134
209
  pbp['FF'] = np.where((pbp['event_type'].isin(fenwick_events)) & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr']), 1, 0)
135
210
  pbp['FA'] = np.where((pbp['event_type'].isin(fenwick_events)) & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr']), 1, 0)
136
- pbp['RushF'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr'])&(pbp['rush_mod']>0), 1, 0)
137
- pbp['RushA'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr'])&(pbp['rush_mod']>0), 1, 0)
138
- pbp['RushFxG'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr'])&(pbp['rush_mod']>0), pbp['xG'], 0)
139
- pbp['RushAxG'] = np.where((pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr'])&(pbp['rush_mod']>0), pbp['xG'], 0)
140
- pbp['RushFG'] = np.where((pbp['event_type'] == "goal") & (pbp['event_team_abbr'] == pbp[f'{team[0]}_team_abbr'])&(pbp['rush_mod']>0), 1, 0)
141
- pbp['RushAG'] = np.where((pbp['event_type'] == "goal") & (pbp['event_team_abbr'] == pbp[f'{team[1]}_team_abbr'])&(pbp['rush_mod']>0), 1, 0)
142
-
143
- stats = pbp.groupby([f'{team[0]}_team_abbr','season']).agg(
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(
144
231
  GP=('game_id','nunique'),
145
232
  TOI=('event_length','sum'),
146
233
  FF=('FF', 'sum'),
@@ -149,16 +236,28 @@ def calc_team(pbp):
149
236
  GA=('GA', 'sum'),
150
237
  xGF=('xGF', 'sum'),
151
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'),
152
251
  RushF=('RushF','sum'),
153
252
  RushA=('RushA','sum'),
154
253
  RushFxG=('RushFxG','sum'),
155
254
  RushAxG=('RushAxG','sum'),
156
255
  RushFG=('RushFG','sum'),
157
256
  RushAG=('RushAG','sum'),
158
- ).reset_index().rename(columns={f'{team[0]}_team_abbr':"Team",'season':"Season"})
257
+ ).reset_index().rename(columns={f'{team[0]}_team_abbr':"Team",'season':"Season",'game_id':'Game'})
159
258
  teams.append(stats)
160
259
 
161
- onice_stats = pd.concat(teams).groupby(['Team','Season']).agg(
260
+ onice_stats = pd.concat(teams).groupby(['Team','Season']+(['Game'] if 'game_id' in second_group else [])).agg(
162
261
  GP=('GP','sum'),
163
262
  TOI=('TOI','sum'),
164
263
  FF=('FF', 'sum'),
@@ -167,6 +266,18 @@ def calc_team(pbp):
167
266
  GA=('GA', 'sum'),
168
267
  xGF=('xGF', 'sum'),
169
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'),
170
281
  RushF=('RushF','sum'),
171
282
  RushA=('RushA','sum'),
172
283
  RushFxG=('RushFxG','sum'),
@@ -181,5 +292,83 @@ def calc_team(pbp):
181
292
  onice_stats['xGA/FA'] = onice_stats['xGA']/onice_stats['FA']
182
293
  onice_stats['GA/xGA'] = onice_stats['GA']/onice_stats['xGA']
183
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)
184
326
 
185
- return onice_stats
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
@@ -38,19 +38,16 @@ def wsba_rink(display_range='offense',rotation = 0):
38
38
  despine=True
39
39
  )
40
40
 
41
- def prep_plot_data(pbp,events,strengths,marker_dict=event_markers,xg='moneypuck'):
41
+ def prep_plot_data(pbp,events,strengths,marker_dict=event_markers):
42
42
  try: pbp['xG']
43
43
  except:
44
- if xg == 'wsba':
45
- pbp = wsba_xG(pbp)
46
- else:
47
- pbp = moneypuck_xG(pbp)
44
+ pbp = wsba_xG(pbp)
48
45
  pbp['xG'] = np.where(pbp['xG'].isna(),0,pbp['xG'])
49
46
 
50
47
  pbp['WSBA'] = pbp['event_player_1_name']+pbp['season'].astype(str)+pbp['event_team_abbr']
51
48
 
52
- pbp['x_plot'] = pbp['y_fixed']*-1
53
- pbp['y_plot'] = pbp['x_fixed']
49
+ pbp['x_plot'] = np.where(pbp['x']<0,-pbp['y_adj'],pbp['y_adj'])
50
+ pbp['y_plot'] = abs(pbp['x_adj'])
54
51
 
55
52
  pbp['home_on_ice'] = pbp['home_on_1'].astype(str) + ";" + pbp['home_on_2'].astype(str) + ";" + pbp['home_on_3'].astype(str) + ";" + pbp['home_on_4'].astype(str) + ";" + pbp['home_on_5'].astype(str) + ";" + pbp['home_on_6'].astype(str)
56
53
  pbp['away_on_ice'] = pbp['away_on_1'].astype(str) + ";" + pbp['away_on_2'].astype(str) + ";" + pbp['away_on_3'].astype(str) + ";" + pbp['away_on_4'].astype(str) + ";" + pbp['away_on_5'].astype(str) + ";" + pbp['away_on_6'].astype(str)
@@ -61,9 +58,7 @@ def prep_plot_data(pbp,events,strengths,marker_dict=event_markers,xg='moneypuck'
61
58
  pbp['size'] = np.where(pbp['xG']<=0,40,pbp['xG']*400)
62
59
  pbp['marker'] = pbp['event_type'].replace(marker_dict)
63
60
 
64
- pbp = pbp.loc[(pbp['event_type'].isin(events))&
65
- (pbp['event_distance']<=89)&
66
- (pbp['x_fixed']<=89)]
61
+ pbp = pbp.loc[(pbp['event_type'].isin(events))]
67
62
 
68
63
  if strengths != 'all':
69
64
  pbp = pbp.loc[(pbp['strength_state'].isin(strengths))]
@@ -81,9 +76,9 @@ def league_shots(pbp,events,strengths):
81
76
 
82
77
  return xgoals_smooth
83
78
 
84
- def plot_skater_shots(pbp, player, season, team, strengths, title = None, marker_dict=event_markers, onice='for', legend=False,xg='moneypuck'):
79
+ def plot_skater_shots(pbp, player, season, team, strengths, title = None, marker_dict=event_markers, onice='for', legend=False):
85
80
  shots = ['missed-shot','shot-on-goal','goal']
86
- pbp = prep_plot_data(pbp,shots,strengths,marker_dict,xg)
81
+ pbp = prep_plot_data(pbp,shots,strengths,marker_dict)
87
82
  pbp = pbp.loc[(pbp['season'].astype(str)==season)&((pbp['away_team_abbr']==team)|(pbp['home_team_abbr']==team))]
88
83
 
89
84
  team_data = pd.read_csv('teaminfo/nhl_teaminfo.csv')
@@ -111,14 +106,14 @@ def plot_skater_shots(pbp, player, season, team, strengths, title = None, marker
111
106
 
112
107
  return fig
113
108
 
114
- def plot_game_events(pbp,game_id,events,strengths,marker_dict=event_markers,team_colors={'away':'secondary','home':'primary'},legend=False,xg='moneypuck'):
115
- pbp = prep_plot_data(pbp,events,strengths,marker_dict,xg)
116
- pbp = pbp.loc[pbp['game_id'].astype(str)==game_id]
117
-
109
+ def plot_game_events(pbp,game_id,events,strengths,marker_dict=event_markers,team_colors={'away':'secondary','home':'primary'},legend=False):
110
+ pbp = prep_plot_data(pbp,events,strengths,marker_dict)
111
+ pbp = pbp.loc[pbp['game_id'].astype(str)==str(game_id)]
112
+
118
113
  away_abbr = list(pbp['away_team_abbr'])[0]
119
114
  home_abbr = list(pbp['home_team_abbr'])[0]
120
115
  date = list(pbp['game_date'])[0]
121
- season = f'{game_id[0:4]}{int(game_id[0:4])+1}'
116
+ season = list(pbp['season'])[0]
122
117
 
123
118
  team_data = pd.read_csv('teaminfo/nhl_teaminfo.csv')
124
119
  team_info ={