Spaces:
Running
Running
Commit ·
b02f184
1
Parent(s): 24c90d1
Add sinker-change
Browse files- convert.py +12 -5
- data.py +33 -0
- pitch_leaderboard.py +3 -3
convert.py
CHANGED
|
@@ -47,6 +47,7 @@ ball_kind = {
|
|
| 47 |
50: 'Eephus', # technically "super" eephus but I haven't encountered a normal one yet
|
| 48 |
51: 'Hard Sinker',
|
| 49 |
52: 'Hard Slider',
|
|
|
|
| 50 |
}
|
| 51 |
|
| 52 |
ball_kind_code = {
|
|
@@ -72,7 +73,8 @@ ball_kind_code = {
|
|
| 72 |
49: 'FC',
|
| 73 |
50: 'EP', # technically "super" eephus but I haven't encountered a normal one yet
|
| 74 |
51: 'HS',
|
| 75 |
-
52: 'HL'
|
|
|
|
| 76 |
}
|
| 77 |
|
| 78 |
general_ball_kind = {
|
|
@@ -99,6 +101,7 @@ general_ball_kind = {
|
|
| 99 |
50: 'Eephus', # technically "super" eephus but I haven't encountered a normal one yet
|
| 100 |
51: 'Sinker',
|
| 101 |
52: 'Vertical Slider',
|
|
|
|
| 102 |
}
|
| 103 |
|
| 104 |
general_ball_kind_code = {
|
|
@@ -124,7 +127,8 @@ general_ball_kind_code = {
|
|
| 124 |
49: 'FC',
|
| 125 |
50: 'EP', # technically "super" eephus but I haven't encountered a normal one yet
|
| 126 |
51: 'SI',
|
| 127 |
-
52: 'VS'
|
|
|
|
| 128 |
}
|
| 129 |
|
| 130 |
basic_ball_kind = {
|
|
@@ -148,9 +152,10 @@ basic_ball_kind = {
|
|
| 148 |
47: 'Fastball',
|
| 149 |
48: 'Fastball',
|
| 150 |
49: 'Fastball',
|
| 151 |
-
50: '
|
| 152 |
51: 'Fastball',
|
| 153 |
52: 'Breaking',
|
|
|
|
| 154 |
}
|
| 155 |
|
| 156 |
basic_ball_kind_code = {
|
|
@@ -174,9 +179,10 @@ basic_ball_kind_code = {
|
|
| 174 |
47: 'FB',
|
| 175 |
48: 'FB',
|
| 176 |
49: 'FB',
|
| 177 |
-
50: '
|
| 178 |
51: 'FB',
|
| 179 |
52: 'BR',
|
|
|
|
| 180 |
}
|
| 181 |
|
| 182 |
verify_and_return_basic_ball_kind_code = create_verify_and_return_fn(basic_ball_kind_code.values())
|
|
@@ -401,7 +407,8 @@ ball_kind_code_to_color = {
|
|
| 401 |
'FC': 'sienna',
|
| 402 |
'EP': 'darkgray', # technically "super" eephus but I haven't encountered a normal one yet
|
| 403 |
'HS': 'darkorange',
|
| 404 |
-
'HL': 'darkkhaki'
|
|
|
|
| 405 |
}
|
| 406 |
|
| 407 |
|
|
|
|
| 47 |
50: 'Eephus', # technically "super" eephus but I haven't encountered a normal one yet
|
| 48 |
51: 'Hard Sinker',
|
| 49 |
52: 'Hard Slider',
|
| 50 |
+
53: 'Sinker-Change' # custom class for changeups that are classified as sinekrs
|
| 51 |
}
|
| 52 |
|
| 53 |
ball_kind_code = {
|
|
|
|
| 73 |
49: 'FC',
|
| 74 |
50: 'EP', # technically "super" eephus but I haven't encountered a normal one yet
|
| 75 |
51: 'HS',
|
| 76 |
+
52: 'HL',
|
| 77 |
+
53: 'SG' # custom class for changeups that are classified as sinekrs
|
| 78 |
}
|
| 79 |
|
| 80 |
general_ball_kind = {
|
|
|
|
| 101 |
50: 'Eephus', # technically "super" eephus but I haven't encountered a normal one yet
|
| 102 |
51: 'Sinker',
|
| 103 |
52: 'Vertical Slider',
|
| 104 |
+
53: 'Changeup'
|
| 105 |
}
|
| 106 |
|
| 107 |
general_ball_kind_code = {
|
|
|
|
| 127 |
49: 'FC',
|
| 128 |
50: 'EP', # technically "super" eephus but I haven't encountered a normal one yet
|
| 129 |
51: 'SI',
|
| 130 |
+
52: 'VS',
|
| 131 |
+
53: 'CH'
|
| 132 |
}
|
| 133 |
|
| 134 |
basic_ball_kind = {
|
|
|
|
| 152 |
47: 'Fastball',
|
| 153 |
48: 'Fastball',
|
| 154 |
49: 'Fastball',
|
| 155 |
+
50: 'Off-speed', # technically "super" eephus but I haven't encountered a normal one yet
|
| 156 |
51: 'Fastball',
|
| 157 |
52: 'Breaking',
|
| 158 |
+
53: 'Off-speed',
|
| 159 |
}
|
| 160 |
|
| 161 |
basic_ball_kind_code = {
|
|
|
|
| 179 |
47: 'FB',
|
| 180 |
48: 'FB',
|
| 181 |
49: 'FB',
|
| 182 |
+
50: 'OS', # technically "super" eephus but I haven't encountered a normal one yet
|
| 183 |
51: 'FB',
|
| 184 |
52: 'BR',
|
| 185 |
+
53: 'OS'
|
| 186 |
}
|
| 187 |
|
| 188 |
verify_and_return_basic_ball_kind_code = create_verify_and_return_fn(basic_ball_kind_code.values())
|
|
|
|
| 407 |
'FC': 'sienna',
|
| 408 |
'EP': 'darkgray', # technically "super" eephus but I haven't encountered a normal one yet
|
| 409 |
'HS': 'darkorange',
|
| 410 |
+
'HL': 'darkkhaki',
|
| 411 |
+
'SG': 'olive'
|
| 412 |
}
|
| 413 |
|
| 414 |
|
data.py
CHANGED
|
@@ -210,6 +210,7 @@ data_df = (
|
|
| 210 |
pl.col('batLR').replace_strict(lr),
|
| 211 |
pl.col('pitLR').replace_strict(lr),
|
| 212 |
pl.col('date').str.to_date('%Y%m%d'),
|
|
|
|
| 213 |
|
| 214 |
pl.when(pl.col('GameKindName').str.contains('Regular Season') | (pl.col('GameKindName') == 'Interleague'))
|
| 215 |
.then(pl.lit('Regular Season'))
|
|
@@ -297,6 +298,38 @@ data_df = (
|
|
| 297 |
.then(pl.lit('Oppo'))
|
| 298 |
.alias('batted_ball_direction')
|
| 299 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 300 |
|
| 301 |
.filter(pl.col('ballKind_code') != '-')
|
| 302 |
.unique()
|
|
|
|
| 210 |
pl.col('batLR').replace_strict(lr),
|
| 211 |
pl.col('pitLR').replace_strict(lr),
|
| 212 |
pl.col('date').str.to_date('%Y%m%d'),
|
| 213 |
+
pl.col('date').str.to_date('%Y%m%d').dt.year().alias('season'), # TO-DO: replace lines that re-compute season with season column
|
| 214 |
|
| 215 |
pl.when(pl.col('GameKindName').str.contains('Regular Season') | (pl.col('GameKindName') == 'Interleague'))
|
| 216 |
.then(pl.lit('Regular Season'))
|
|
|
|
| 298 |
.then(pl.lit('Oppo'))
|
| 299 |
.alias('batted_ball_direction')
|
| 300 |
)
|
| 301 |
+
# some sinkers are really changeups
|
| 302 |
+
.with_columns(
|
| 303 |
+
pl.when(pl.col('x').is_not_null() & pl.col('y').is_not_null() & (pl.col('ballSpeed') > 0))
|
| 304 |
+
.then('ballSpeed')
|
| 305 |
+
.mean()
|
| 306 |
+
.over('pitId', 'season', 'ballKind_code')
|
| 307 |
+
.alias('avg_velo')
|
| 308 |
+
)
|
| 309 |
+
.with_columns(
|
| 310 |
+
pl.when(pl.col('general_ballKind_code') == '4S')
|
| 311 |
+
.then('avg_velo')
|
| 312 |
+
.max()
|
| 313 |
+
.over('pitId', 'season')
|
| 314 |
+
.alias('4S_velo')
|
| 315 |
+
)
|
| 316 |
+
.with_columns(
|
| 317 |
+
(
|
| 318 |
+
(pl.col('ballKind_code') == 'SI')
|
| 319 |
+
& (pl.col('avg_velo') < 140)
|
| 320 |
+
& (pl.col('4S_velo') - pl.col('avg_velo') > 3)
|
| 321 |
+
)
|
| 322 |
+
.alias('replace_sinker'),
|
| 323 |
+
)
|
| 324 |
+
.with_columns(
|
| 325 |
+
pl.when('replace_sinker').then(pl.lit(ball_kind[53])).otherwise('ballKind').alias('ballKind'),
|
| 326 |
+
pl.when('replace_sinker').then(pl.lit(ball_kind_code[53])).otherwise('ballKind_code').alias('ballKind_code'),
|
| 327 |
+
pl.when('replace_sinker').then(pl.lit(general_ball_kind[53])).otherwise('general_ballKind').alias('general_ballKind'),
|
| 328 |
+
pl.when('replace_sinker').then(pl.lit(general_ball_kind_code[53])).otherwise('general_ballKind_code').alias('general_ballKind_code'),
|
| 329 |
+
pl.when('replace_sinker').then(pl.lit(basic_ball_kind[53])).otherwise('basic_ballKind').alias('basic_ballKind'),
|
| 330 |
+
pl.when('replace_sinker').then(pl.lit(basic_ball_kind_code[53])).otherwise('basic_ballKind_code').alias('basic_ballKind_code'),
|
| 331 |
+
)
|
| 332 |
+
.drop('replace_sinker')
|
| 333 |
|
| 334 |
.filter(pl.col('ballKind_code') != '-')
|
| 335 |
.unique()
|
pitch_leaderboard.py
CHANGED
|
@@ -157,9 +157,9 @@ def create_pitch_leaderboard(player_team_type):
|
|
| 157 |
return [create_df_value(cols) for cols in theme_to_cols.values()]
|
| 158 |
|
| 159 |
|
| 160 |
-
|
| 161 |
-
|
| 162 |
-
end_datetime_init = now
|
| 163 |
with gr.Blocks() as app:
|
| 164 |
gr.Markdown(f'# {player_team_type.title()} Pitch Leaderboard')
|
| 165 |
with gr.Row():
|
|
|
|
| 157 |
return [create_df_value(cols) for cols in theme_to_cols.values()]
|
| 158 |
|
| 159 |
|
| 160 |
+
start_datetime_init = datetime(data_df['season'].max(), 1, 1)
|
| 161 |
+
max_date = data_df['date'].max()
|
| 162 |
+
end_datetime_init = min(datetime.now(), datetime(max_date.year, max_date.month, max_date.day))
|
| 163 |
with gr.Blocks() as app:
|
| 164 |
gr.Markdown(f'# {player_team_type.title()} Pitch Leaderboard')
|
| 165 |
with gr.Row():
|