Spaces:
Running
Running
Commit
·
bf098fd
1
Parent(s):
ab63d80
Add PLUS%
Browse files- pitch_leaderboard.py +2 -4
- player_team_leaderboard.py +2 -4
- 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:
|