patrickramos commited on
Commit
bf098fd
·
1 Parent(s): ab63d80
Files changed (3) hide show
  1. pitch_leaderboard.py +2 -4
  2. player_team_leaderboard.py +2 -4
  3. stats.py +7 -33
pitch_leaderboard.py CHANGED
@@ -40,19 +40,17 @@ def create_pitch_leaderboard(player_team_type):
40
  if team:
41
  prefix_cols = [col for col in prefix_cols if col not in ('Pitcher', 'Throws')]
42
  theme_to_cols = {
43
- 'Plate Discipline': ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Con%', 'O-Con%', 'SwStr%', 'Whiff%', 'CSW%', 'Strike%', 'Ball%', 'F-Str%', 'PAR%'],
44
  'Batted Ball': ['GB%', 'FB%', 'LD%', 'OFFB%', 'IFFB%', 'AIR%'],
45
  'Approach': ['Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%', 'Behind%']
46
  }
47
 
48
  else:
49
  prefix_cols = ['Batter', 'Team', 'Bats', 'Pitch', 'Pitch (General)', 'Count', 'Usage', 'Avg Velo', 'Max Velo']
50
- plate_disc_cols = ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%']
51
- batted_ball_cols = ['GB%', 'FB%', 'LD%', 'OFFB%', 'IFFB%', 'AIR%']
52
  if team:
53
  prefix_cols = [col for col in prefix_cols if col not in ('Batter', 'Bats')]
54
  theme_to_cols = {
55
- 'Plate Discipline': ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Con%', 'O-Con%', 'SwStr%', 'Whiff%', 'CSW%'],
56
  'Batted Ball': ['GB%', 'FB%', 'LD%', 'OFFB%', 'IFFB%', 'AIR%']
57
  }
58
 
 
40
  if team:
41
  prefix_cols = [col for col in prefix_cols if col not in ('Pitcher', 'Throws')]
42
  theme_to_cols = {
43
+ 'Plate Discipline': ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Con%', 'O-Con%', 'SwStr%', 'Whiff%', 'CSW%', 'Strike%', 'Ball%', 'F-Str%', 'PAR%', 'PLUS%'],
44
  'Batted Ball': ['GB%', 'FB%', 'LD%', 'OFFB%', 'IFFB%', 'AIR%'],
45
  'Approach': ['Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%', 'Behind%']
46
  }
47
 
48
  else:
49
  prefix_cols = ['Batter', 'Team', 'Bats', 'Pitch', 'Pitch (General)', 'Count', 'Usage', 'Avg Velo', 'Max Velo']
 
 
50
  if team:
51
  prefix_cols = [col for col in prefix_cols if col not in ('Batter', 'Bats')]
52
  theme_to_cols = {
53
+ 'Plate Discipline': ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Con%', 'O-Con%', 'SwStr%', 'Whiff%', 'CSW%', 'PLUS%'],
54
  'Batted Ball': ['GB%', 'FB%', 'LD%', 'OFFB%', 'IFFB%', 'AIR%']
55
  }
56
 
player_team_leaderboard.py CHANGED
@@ -36,7 +36,7 @@ def create_player_team_leaderboard_app(player_team_type):
36
  if team:
37
  prefix_cols = [col for col in prefix_cols if col not in ('Pitcher', 'Throws')]
38
  theme_to_cols = {
39
- 'Plate Discipline': ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Con%', 'O-Con%', 'SwStr%', 'Whiff%', 'CSW%', 'Strike%', 'Ball%', 'F-Str%', 'PAR%'],
40
  'Batted Ball': ['GB%', 'FB%', 'LD%', 'OFFB%', 'IFFB%', 'AIR%'],
41
  'Approach': ['Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%', 'Behind%']
42
  }
@@ -46,12 +46,10 @@ def create_player_team_leaderboard_app(player_team_type):
46
 
47
  else:
48
  prefix_cols = ['Batter', 'Team', 'Bats', 'PA', 'K%', 'BB%']
49
- plate_disc_cols = ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Contact%', 'O-Contact%', 'SwStr%', 'Whiff%', 'CSW%']
50
- batted_ball_cols = ['GB%', 'FB%', 'LD%', 'OFFB%', 'IFFB%', 'AIR%']
51
  if team:
52
  prefix_cols = [col for col in prefix_cols if col not in ('Batter', 'Bats')]
53
  theme_to_cols = {
54
- 'Plate Discipline': ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Con%', 'O-Con%', 'SwStr%', 'Whiff%', 'CSW%'],
55
  'Batted Ball': ['GB%', 'FB%', 'LD%', 'OFFB%', 'IFFB%', 'AIR%']
56
  }
57
  all_cols = prefix_cols + sum(list(theme_to_cols.values()), [])
 
36
  if team:
37
  prefix_cols = [col for col in prefix_cols if col not in ('Pitcher', 'Throws')]
38
  theme_to_cols = {
39
+ 'Plate Discipline': ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Con%', 'O-Con%', 'SwStr%', 'Whiff%', 'CSW%', 'Strike%', 'Ball%', 'F-Str%', 'PAR%', 'PLUS%'],
40
  'Batted Ball': ['GB%', 'FB%', 'LD%', 'OFFB%', 'IFFB%', 'AIR%'],
41
  'Approach': ['Zone%', 'Arm%', 'Glove%', 'High%', 'Low%', 'MM%', 'Behind%']
42
  }
 
46
 
47
  else:
48
  prefix_cols = ['Batter', 'Team', 'Bats', 'PA', 'K%', 'BB%']
 
 
49
  if team:
50
  prefix_cols = [col for col in prefix_cols if col not in ('Batter', 'Bats')]
51
  theme_to_cols = {
52
+ 'Plate Discipline': ['Swing%', 'Z-Swing%', 'Chase%', 'Contact%', 'Z-Con%', 'O-Con%', 'SwStr%', 'Whiff%', 'CSW%', 'PLUS%'],
53
  'Batted Ball': ['GB%', 'FB%', 'LD%', 'OFFB%', 'IFFB%', 'AIR%']
54
  }
55
  all_cols = prefix_cols + sum(list(theme_to_cols.values()), [])
stats.py CHANGED
@@ -38,6 +38,12 @@ is_ball = pl.col('presult').is_in(verify_and_return_presult(['Ball', 'Walk']))
38
  is_non_ball = pl.col('pitch') & ~is_ball # pitches that are not balls i.e. no catcher interference, etc.
39
  is_two_str = pl.col('before_s') == 2 # named this way in case I use two_str for 2-Str%
40
  first_count = (pl.col('before_s') == 0) & (pl.col('before_b') == 0)
 
 
 
 
 
 
41
 
42
  register_stat('FB Velo', pl.col('FB Velo').max(), False, Player.PITCHER)
43
  register_stat('K%', pl.when(pl.col('presult').str.contains('strikeout')).then(1).otherwise(0).sum() / pl.col('pa_code').unique().len(), True, Player.PITCHER)
@@ -55,6 +61,7 @@ register_stat('Ball%', is_ball.sum() / pl.col('pitch').sum(), True, Player.BATTE
55
  register_stat('Strike%', is_non_ball.sum() / pl.col('pitch').sum(), True, Player.PITCHER)
56
  register_stat('F-Str%', (is_non_ball & first_count).sum() / first_count.sum(), True, Player.PITCHER)
57
  register_stat('PAR%', ((is_two_str & pl.col('presult').str.contains('strikeout')).sum()) / is_two_str.sum(), True, Player.PITCHER)
 
58
  register_stat('Behind%', ((pl.col('before_b') > pl.col('before_s')) & (pl.col('before_s') < 2) & (pl.col('before_b') > 1)).sum() / pl.len(), True, Player.BATTER)
59
  register_stat('Zone%', pl.col('zone').sum() / pl.col('pitch').sum(), True, Player.PITCHER)
60
  register_stat('Glove%', (pl.when(pl.col('pitLR') == 'r').then(pl.col('x') < 0).otherwise(pl.col('x') > 0)).mean(), True, None)
@@ -74,39 +81,6 @@ register_stat('Usage', pl.len()/pl.first('Pitches'), True, None)
74
  register_stat('Avg Velo', pl.when(valid_pitch).then('mph').mean(), False, None)
75
  register_stat('Max Velo', pl.col('mph').max(), False, None)
76
 
77
- # swing = (pl.col('swing').sum() / pl.col('pitch').sum()).alias('Swing%')
78
- # z_swing = ((pl.col('swing') & pl.col('zone')).sum() / pl.col('zone').sum()).alias('Z-Swing%')
79
- # chase = ((pl.col('swing') & ~pl.col('zone')).sum() / (~pl.col('zone')).sum()).alias('Chase%')
80
- # contact = ((pl.col('swing') & ~pl.col('whiff')).sum()/pl.col('swing').sum()).alias('Contact%')
81
- # z_con = ((pl.col('zone') & pl.col('swing') & ~pl.col('whiff')).sum()/(pl.col('zone') & pl.col('swing')).sum()).alias('Z-Contact%')
82
- # o_con = ((~pl.col('zone') & pl.col('swing') & ~pl.col('whiff')).sum()/(~pl.col('zone') & pl.col('swing')).sum()).alias('O-Contact%')
83
- # whiff = (pl.col('whiff').sum() / pl.col('swing').sum()).alias('Whiff%')
84
- # swstr = (pl.col('whiff').sum() / pl.col('pitch').sum()).alias('SwStr%')
85
- # csw = (pl.col('csw').sum() / pl.col('pitch').sum()).alias('CSW%')
86
- # is_ball = pl.col('presult').is_in(verify_and_return_presult(['Ball', 'Walk']))
87
- # is_non_ball = pl.col('pitch') & ~is_ball # pitches that are not balls i.e. no catcher interference, etc.
88
- # ball = (is_ball.sum() / pl.col('pitch').sum()).alias('Ball%')
89
- # strike = (is_non_ball.sum() / pl.col('pitch').sum()).alias('Strike%')
90
- # is_two_str = pl.col('before_s') == 2 # named this way in case I use two_str for 2-Str%
91
- # first_count = (pl.col('before_s') == 0) & (pl.col('before_b') == 0)
92
- # f_strike = ((is_non_ball & first_count).sum() / first_count.sum()).alias('F-Str%')
93
- # par = (((is_two_str & pl.col('presult').str.contains('strikeout')).sum()) / is_two_str.sum()).alias('PAR%')
94
- # behind = (((pl.col('before_b') > pl.col('before_s')) & (pl.col('before_s') < 2) & (pl.col('before_b') > 1)).sum() / pl.len()).alias('Behind%')
95
- # zone = (pl.col('zone').sum() / pl.col('pitch').sum()).alias('Zone%')
96
- # glove = (pl.when(pl.col('pitLR') == 'r').then(pl.col('x') < 0).otherwise(pl.col('x') > 0)).mean().alias('Glove%')
97
- # arm = (pl.when(pl.col('pitLR') == 'r').then(pl.col('x') >= 0).otherwise(pl.col('x') <= 0)).mean().alias('Arm%')
98
- # high = (pl.col('y') > 125).mean().alias('High%')
99
- # low = (pl.col('y') <= 125).mean().alias('Low%')
100
- # mm = (pl.col('x').is_between(-20, 20) & pl.col('y').is_between(100, 100+50)).mean().alias('MM%')
101
- # obp = (
102
- # pl.col('presult').is_in(verify_and_return_presult(['Single', 'Double', 'Triple', 'Home run', 'Walk', 'Inside-the-park home run', 'Hit by pitch'])).sum() /
103
- # (pl.col('AB').first() + pl.col('presult').is_in(verify_and_return_presult(['Walk', 'Hit by pitch', 'Sacrifice fly'])).sum())
104
- # ).round(3).alias('OBP')
105
- # h = pl.col('presult').is_in(verify_and_return_presult(['Single', 'Double', 'Triple', 'Home run', 'Inside-the-park home run'])).sum().alias('H')
106
- # bb = pl.col('presult').is_in(verify_and_return_presult(['Walk'])).sum().alias('BB')
107
- # hbp = pl.col('presult').is_in(verify_and_return_presult(['Hit by pitch'])).sum().alias('HBP')
108
- # sf = pl.col('presult').is_in(verify_and_return_presult(['Sacrifice fly'])).sum().alias('SF')
109
-
110
 
111
  def filter_data_by_date_and_game_kind(data, start_date=None, end_date=None, game_kind=None):
112
  if start_date is not None:
 
38
  is_non_ball = pl.col('pitch') & ~is_ball # pitches that are not balls i.e. no catcher interference, etc.
39
  is_two_str = pl.col('before_s') == 2 # named this way in case I use two_str for 2-Str%
40
  first_count = (pl.col('before_s') == 0) & (pl.col('before_b') == 0)
41
+ is_bip_out = pl.col('presult').is_in(verify_and_return_presult([
42
+ 'Groundout', 'Flyout', 'Lineout', 'Groundout (Double play)',
43
+ 'Foul fly', 'Foul line (?)',
44
+ 'Sacrifice bunt', 'Sacrifice fly',
45
+ "Fielder's choice", "Sacrifice fielder's choice"
46
+ ]))
47
 
48
  register_stat('FB Velo', pl.col('FB Velo').max(), False, Player.PITCHER)
49
  register_stat('K%', pl.when(pl.col('presult').str.contains('strikeout')).then(1).otherwise(0).sum() / pl.col('pa_code').unique().len(), True, Player.PITCHER)
 
61
  register_stat('Strike%', is_non_ball.sum() / pl.col('pitch').sum(), True, Player.PITCHER)
62
  register_stat('F-Str%', (is_non_ball & first_count).sum() / first_count.sum(), True, Player.PITCHER)
63
  register_stat('PAR%', ((is_two_str & pl.col('presult').str.contains('strikeout')).sum()) / is_two_str.sum(), True, Player.PITCHER)
64
+ register_stat('PLUS%', (pl.col('csw') | (pl.col('presult') == 'Foul') | is_bip_out).sum() / pl.col('pitch').sum(), True, Player.PITCHER)
65
  register_stat('Behind%', ((pl.col('before_b') > pl.col('before_s')) & (pl.col('before_s') < 2) & (pl.col('before_b') > 1)).sum() / pl.len(), True, Player.BATTER)
66
  register_stat('Zone%', pl.col('zone').sum() / pl.col('pitch').sum(), True, Player.PITCHER)
67
  register_stat('Glove%', (pl.when(pl.col('pitLR') == 'r').then(pl.col('x') < 0).otherwise(pl.col('x') > 0)).mean(), True, None)
 
81
  register_stat('Avg Velo', pl.when(valid_pitch).then('mph').mean(), False, None)
82
  register_stat('Max Velo', pl.col('mph').max(), False, None)
83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
  def filter_data_by_date_and_game_kind(data, start_date=None, end_date=None, game_kind=None):
86
  if start_date is not None: