patrickramos commited on
Commit
0e26e9f
·
1 Parent(s): 6be2b70
Files changed (3) hide show
  1. pitch_leaderboard.py +3 -3
  2. player_team_leaderboard.py +3 -3
  3. stats.py +8 -5
pitch_leaderboard.py CHANGED
@@ -10,9 +10,9 @@ from stats import compute_pitch_stats, filter_data_by_date_and_game_kind
10
  from convert import ball_kind, ball_kind_to_color, get_text_color_from_color, team_names_short_to_color, get_text_color_from_team
11
  from plotting import stat_cmap
12
 
13
- STATS = ['Count', 'Usage', 'Avg Velo', 'Max Velo', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%']
14
- PCT_STATS = ['Usage', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%']
15
- STATS_WITH_PCTLS = ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%']
16
  COLUMNS = ['Pitcher', 'Team', 'Throws', 'Pitch', 'Pitch (General)'] + STATS
17
 
18
  PITCH_TYPES = [pitch_type for pitch_type in ball_kind.values() if pitch_type != '-']
 
10
  from convert import ball_kind, ball_kind_to_color, get_text_color_from_color, team_names_short_to_color, get_text_color_from_team
11
  from plotting import stat_cmap
12
 
13
+ STATS = ['Count', 'Usage', 'Avg Velo', 'Max Velo', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'Ball%', 'GB%', 'FB%', 'LD%', 'Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%']
14
+ PCT_STATS = ['Usage', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'Ball%', 'GB%', 'FB%', 'LD%', 'Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%']
15
+ STATS_WITH_PCTLS = ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'Ball%', 'GB%', 'FB%', 'LD%', 'Zone%']
16
  COLUMNS = ['Pitcher', 'Team', 'Throws', 'Pitch', 'Pitch (General)'] + STATS
17
 
18
  PITCH_TYPES = [pitch_type for pitch_type in ball_kind.values() if pitch_type != '-']
player_team_leaderboard.py CHANGED
@@ -57,9 +57,9 @@ def create_player_team_leaderboard_app(player_team_type):
57
 
58
  # stats
59
  if pitching:
60
- pct_stats = ['K%', 'BB%', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%']
61
- stats_with_pctls = ['FB Velo', 'K%', 'BB%', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%']
62
- cols = ['Pitcher', 'Team', 'Throws', 'IP', 'TBF', 'FB Velo', 'K%', 'BB%', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%']
63
  if team:
64
  cols = [col for col in cols if col not in ('Pitcher', 'Throws')]
65
  else:
 
57
 
58
  # stats
59
  if pitching:
60
+ pct_stats = ['K%', 'BB%', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'Ball%', 'GB%', 'FB%', 'LD%', 'Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%']
61
+ stats_with_pctls = ['FB Velo', 'K%', 'BB%', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'Ball%', 'GB%', 'FB%', 'LD%', 'Zone%']
62
+ cols = ['Pitcher', 'Team', 'Throws', 'IP', 'TBF', 'FB Velo', 'K%', 'BB%', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'Ball%', 'GB%', 'FB%', 'LD%', 'Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%']
63
  if team:
64
  cols = [col for col in cols if col not in ('Pitcher', 'Throws')]
65
  else:
stats.py CHANGED
@@ -17,6 +17,7 @@ o_con = ((~pl.col('zone') & pl.col('swing') & ~pl.col('whiff')).sum()/(~pl.col('
17
  whiff = (pl.col('whiff').sum() / pl.col('swing').sum()).alias('Whiff%')
18
  swstr = (pl.col('whiff').sum() / pl.col('pitch').sum()).alias('SwStr%')
19
  csw = (pl.col('csw').sum() / pl.col('pitch').sum()).alias('CSW%')
 
20
  zone = (pl.col('zone').sum() / pl.col('pitch').sum()).alias('Zone%')
21
  glove = (pl.when(pl.col('pitLR') == 'r').then(pl.col('x') < 0).otherwise(pl.col('x') > 0)).mean().alias('Glove%')
22
  arm = (pl.when(pl.col('pitLR') == 'r').then(pl.col('x') >= 0).otherwise(pl.col('x') <= 0)).mean().alias('Arm%')
@@ -138,6 +139,7 @@ def compute_pitch_stats(data, player_type, pitch_class_type, min_pitches=1, pitc
138
  whiff,
139
  swstr,
140
  csw,
 
141
  zone,
142
  glove,
143
  arm,
@@ -160,8 +162,8 @@ def compute_pitch_stats(data, player_type, pitch_class_type, min_pitches=1, pitc
160
  )
161
  .drop('G', 'F', 'B', 'P', 'L', 'null')
162
  .with_columns(
163
- (pl.when(pl.col('qualified')).then(pl.col(stat)).rank(descending=((stat in ['FB%', 'LD%'] or 'Contact%' in stat)))/pl.when(pl.col('qualified')).then(pl.col(stat)).count()).alias(f'{stat}_pctl')
164
- for stat in ['Avg KPH', 'Max KPH', 'Avg MPH', 'Max MPH', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%']
165
  )
166
  .rename({pitch_col: 'ballKind_code', pitch_name_col: 'ballKind'} if pitch_class_type == 'general' else {})
167
  .sort(id_cols[0], 'count', descending=[False, True])
@@ -222,9 +224,9 @@ def compute_player_stats(data, player_type, qual='qualified', pitcher_lr='both',
222
 
223
  # percentile ascending/descending
224
  if pitching:
225
- stat_descending_pctl = lambda stat: stat in ['BB%', 'FB%', 'LD%', 'Z-Swing%', 'OBP'] or 'Contact%' in stat
226
  else:
227
- stat_descending_pctl = lambda stat: not (stat in ['BB%', 'FB%', 'LD%', 'Swing%', 'Z-Swing%', 'OBP'] or 'Contact%' in stat)
228
 
229
  # col names
230
  match player_type:
@@ -271,6 +273,7 @@ def compute_player_stats(data, player_type, qual='qualified', pitcher_lr='both',
271
  whiff,
272
  swstr,
273
  csw,
 
274
  zone,
275
  glove,
276
  arm,
@@ -297,7 +300,7 @@ def compute_player_stats(data, player_type, qual='qualified', pitcher_lr='both',
297
  .drop('G', 'F', 'B', 'P', 'L')
298
  .with_columns(
299
  (pl.when(pl.col('qualified')).then(pl.col(stat)).rank(descending=stat_descending_pctl(stat))/pl.when(pl.col('qualified')).then(pl.col(stat)).count()).alias(f'{stat}_pctl')
300
- for stat in ['FB Velo', 'K%', 'BB%', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'GB%', 'FB%', 'LD%', 'Zone%', 'OBP']
301
  )
302
  .sort(qual_col, descending=True)
303
  )
 
17
  whiff = (pl.col('whiff').sum() / pl.col('swing').sum()).alias('Whiff%')
18
  swstr = (pl.col('whiff').sum() / pl.col('pitch').sum()).alias('SwStr%')
19
  csw = (pl.col('csw').sum() / pl.col('pitch').sum()).alias('CSW%')
20
+ ball = ((pl.col('presult') == 'Ball').sum() / pl.col('pitch').sum()).alias('Ball%')
21
  zone = (pl.col('zone').sum() / pl.col('pitch').sum()).alias('Zone%')
22
  glove = (pl.when(pl.col('pitLR') == 'r').then(pl.col('x') < 0).otherwise(pl.col('x') > 0)).mean().alias('Glove%')
23
  arm = (pl.when(pl.col('pitLR') == 'r').then(pl.col('x') >= 0).otherwise(pl.col('x') <= 0)).mean().alias('Arm%')
 
139
  whiff,
140
  swstr,
141
  csw,
142
+ ball,
143
  zone,
144
  glove,
145
  arm,
 
162
  )
163
  .drop('G', 'F', 'B', 'P', 'L', 'null')
164
  .with_columns(
165
+ (pl.when(pl.col('qualified')).then(pl.col(stat)).rank(descending=((stat in ['FB%', 'LD%', 'Ball%'] or 'Contact%' in stat)))/pl.when(pl.col('qualified')).then(pl.col(stat)).count()).alias(f'{stat}_pctl')
166
+ for stat in ['Avg KPH', 'Max KPH', 'Avg MPH', 'Max MPH', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'Ball%', 'GB%', 'FB%', 'LD%', 'Zone%']
167
  )
168
  .rename({pitch_col: 'ballKind_code', pitch_name_col: 'ballKind'} if pitch_class_type == 'general' else {})
169
  .sort(id_cols[0], 'count', descending=[False, True])
 
224
 
225
  # percentile ascending/descending
226
  if pitching:
227
+ stat_descending_pctl = lambda stat: stat in ['BB%', 'Ball%', 'FB%', 'LD%', 'Z-Swing%', 'OBP'] or 'Contact%' in stat
228
  else:
229
+ stat_descending_pctl = lambda stat: not (stat in ['BB%', 'Ball%', 'FB%', 'LD%', 'Swing%', 'Z-Swing%', 'OBP'] or 'Contact%' in stat)
230
 
231
  # col names
232
  match player_type:
 
273
  whiff,
274
  swstr,
275
  csw,
276
+ ball,
277
  zone,
278
  glove,
279
  arm,
 
300
  .drop('G', 'F', 'B', 'P', 'L')
301
  .with_columns(
302
  (pl.when(pl.col('qualified')).then(pl.col(stat)).rank(descending=stat_descending_pctl(stat))/pl.when(pl.col('qualified')).then(pl.col(stat)).count()).alias(f'{stat}_pctl')
303
+ for stat in ['FB Velo', 'K%', 'BB%', 'Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%', 'Ball%', 'GB%', 'FB%', 'LD%', 'Zone%', 'OBP']
304
  )
305
  .sort(qual_col, descending=True)
306
  )