Spaces:
Running
Running
James McCool
commited on
Commit
·
a5c1797
1
Parent(s):
acfed57
Added framework for play-by-play data to be used in rotations.
Browse files- src/streamlit_app.py +47 -3
src/streamlit_app.py
CHANGED
|
@@ -25,8 +25,10 @@ season_data_cols = ['Touches', 'Touch/Min', 'Pts', 'FGM', 'FGA', 'FG%', 'FG3M',
|
|
| 25 |
'FG3%', 'FTM', 'FTA', 'FT%', 'OREB Chance', 'OREB', 'DREB Chance', 'DREB', 'REB Chance', 'REB',
|
| 26 |
'Passes', 'Alt Assists', 'FT Assists', 'Assists', 'Stl', 'Blk', 'Tov', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy',
|
| 27 |
'FPPM', 'Rebound%', 'Assists/Pass', 'Fantasy/Touch', 'FD Fantasy/Touch']
|
| 28 |
-
|
| 29 |
'Fantasy', 'FD_Fantasy']
|
|
|
|
|
|
|
| 30 |
|
| 31 |
percentages_format = {'PG': '{:.2%}', 'SG': '{:.2%}', 'SF': '{:.2%}', 'PF': '{:.2%}', 'C': '{:.2%}'}
|
| 32 |
|
|
@@ -172,6 +174,42 @@ def init_baselines(data_req: str):
|
|
| 172 |
game_rot[data_cols] = game_rot[data_cols].apply(pd.to_numeric, errors='coerce')
|
| 173 |
game_rot['spread'] = game_rot['GAME_ID'].map(spread_dict)
|
| 174 |
game_rot['GAME_DATE'] = pd.to_datetime(game_rot['GAME_DATE']).dt.date
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 175 |
|
| 176 |
return gamelog_table, game_rot, timestamp
|
| 177 |
|
|
@@ -744,7 +782,10 @@ if selected_tab == 'Game Rotations':
|
|
| 744 |
fig.add_vline(x=24, line_width=3, line_dash="dash", line_color="green")
|
| 745 |
fig.add_vline(x=36, line_width=3, line_dash="dash", line_color="green")
|
| 746 |
|
| 747 |
-
|
|
|
|
|
|
|
|
|
|
| 748 |
game_rot_stats = game_rot_stats.drop_duplicates(subset='backlog_lookup')
|
| 749 |
|
| 750 |
# pages = pages.set_index('Player')
|
|
@@ -765,7 +806,10 @@ if selected_tab == 'Game Rotations':
|
|
| 765 |
stats_disp = st.container()
|
| 766 |
check_rotation = working_data[working_data['backlog_lookup'] == game_id_var]
|
| 767 |
check_rotation = check_rotation.sort_values(by='Start', ascending=True)
|
| 768 |
-
|
|
|
|
|
|
|
|
|
|
| 769 |
game_rot_stats = game_rot_stats.drop_duplicates(subset='PLAYER_NAME')
|
| 770 |
|
| 771 |
# Create figure
|
|
|
|
| 25 |
'FG3%', 'FTM', 'FTA', 'FT%', 'OREB Chance', 'OREB', 'DREB Chance', 'DREB', 'REB Chance', 'REB',
|
| 26 |
'Passes', 'Alt Assists', 'FT Assists', 'Assists', 'Stl', 'Blk', 'Tov', 'PF', 'DD', 'TD', 'Fantasy', 'FD_Fantasy',
|
| 27 |
'FPPM', 'Rebound%', 'Assists/Pass', 'Fantasy/Touch', 'FD Fantasy/Touch']
|
| 28 |
+
game_rot_cols_base = ['PLAYER_NAME', 'backlog_lookup', 'spread', 'MIN', 'PTS', 'FGM', 'FGA', 'FG3M', 'FG3A', 'FTM', 'FTA', 'REB', 'AST', 'STL', 'BLK', 'TOV', 'PF',
|
| 29 |
'Fantasy', 'FD_Fantasy']
|
| 30 |
+
game_rot_cols_stint = ['stint_PTS', 'stint_FGM', 'stint_FGA', 'stint_FG3M', 'stint_REB', 'stint_AST', 'stint_STL', 'stint_BLK', 'stint_TOV', 'stint_PF', 'stint_Fantasy', 'stint_FD_Fantasy']
|
| 31 |
+
game_rot_cols = game_rot_cols_base + game_rot_cols_stint
|
| 32 |
|
| 33 |
percentages_format = {'PG': '{:.2%}', 'SG': '{:.2%}', 'SF': '{:.2%}', 'PF': '{:.2%}', 'C': '{:.2%}'}
|
| 34 |
|
|
|
|
| 174 |
game_rot[data_cols] = game_rot[data_cols].apply(pd.to_numeric, errors='coerce')
|
| 175 |
game_rot['spread'] = game_rot['GAME_ID'].map(spread_dict)
|
| 176 |
game_rot['GAME_DATE'] = pd.to_datetime(game_rot['GAME_DATE']).dt.date
|
| 177 |
+
|
| 178 |
+
# Query play-by-play stint stats
|
| 179 |
+
try:
|
| 180 |
+
collection = db["playbyplay_stints"]
|
| 181 |
+
cursor = collection.find()
|
| 182 |
+
stint_stats = pd.DataFrame(list(cursor))
|
| 183 |
+
|
| 184 |
+
if len(stint_stats) > 0:
|
| 185 |
+
# Create stint_id in game_rot for merging
|
| 186 |
+
game_rot['stint_id'] = (game_rot['GAME_ID'].astype(str) + '_' +
|
| 187 |
+
game_rot['PERSON_ID'].astype(str) + '_' +
|
| 188 |
+
game_rot['Start'].astype(str))
|
| 189 |
+
|
| 190 |
+
# Select columns to merge from stint_stats
|
| 191 |
+
stint_cols = ['stint_id', 'stint_PTS', 'stint_FGM', 'stint_FGA', 'stint_FG3M', 'stint_FG3A',
|
| 192 |
+
'stint_FTM', 'stint_FTA', 'stint_REB', 'stint_OREB', 'stint_DREB',
|
| 193 |
+
'stint_AST', 'stint_STL', 'stint_BLK', 'stint_TOV', 'stint_PF',
|
| 194 |
+
'stint_Fantasy', 'stint_FD_Fantasy']
|
| 195 |
+
|
| 196 |
+
# Keep only columns that exist
|
| 197 |
+
available_cols = [col for col in stint_cols if col in stint_stats.columns]
|
| 198 |
+
stint_stats_subset = stint_stats[available_cols]
|
| 199 |
+
|
| 200 |
+
# Convert stint stats to numeric
|
| 201 |
+
numeric_cols = [col for col in available_cols if col != 'stint_id']
|
| 202 |
+
stint_stats_subset[numeric_cols] = stint_stats_subset[numeric_cols].apply(pd.to_numeric, errors='coerce')
|
| 203 |
+
|
| 204 |
+
# Merge stint stats with rotations
|
| 205 |
+
game_rot = game_rot.merge(stint_stats_subset, on='stint_id', how='left')
|
| 206 |
+
|
| 207 |
+
# Fill NaN stint stats with 0
|
| 208 |
+
for col in numeric_cols:
|
| 209 |
+
if col in game_rot.columns:
|
| 210 |
+
game_rot[col] = game_rot[col].fillna(0)
|
| 211 |
+
except Exception as e:
|
| 212 |
+
print(f"Note: Could not load stint stats: {e}")
|
| 213 |
|
| 214 |
return gamelog_table, game_rot, timestamp
|
| 215 |
|
|
|
|
| 782 |
fig.add_vline(x=24, line_width=3, line_dash="dash", line_color="green")
|
| 783 |
fig.add_vline(x=36, line_width=3, line_dash="dash", line_color="green")
|
| 784 |
|
| 785 |
+
# Dynamically build columns list based on what exists in data
|
| 786 |
+
available_cols = [col for col in game_rot_cols_base if col in check_rotation.columns]
|
| 787 |
+
available_cols += [col for col in game_rot_cols_stint if col in check_rotation.columns]
|
| 788 |
+
game_rot_stats = check_rotation.reindex(available_cols, axis="columns")
|
| 789 |
game_rot_stats = game_rot_stats.drop_duplicates(subset='backlog_lookup')
|
| 790 |
|
| 791 |
# pages = pages.set_index('Player')
|
|
|
|
| 806 |
stats_disp = st.container()
|
| 807 |
check_rotation = working_data[working_data['backlog_lookup'] == game_id_var]
|
| 808 |
check_rotation = check_rotation.sort_values(by='Start', ascending=True)
|
| 809 |
+
# Dynamically build columns list based on what exists in data
|
| 810 |
+
available_cols = [col for col in game_rot_cols_base if col in check_rotation.columns]
|
| 811 |
+
available_cols += [col for col in game_rot_cols_stint if col in check_rotation.columns]
|
| 812 |
+
game_rot_stats = check_rotation.reindex(available_cols, axis="columns")
|
| 813 |
game_rot_stats = game_rot_stats.drop_duplicates(subset='PLAYER_NAME')
|
| 814 |
|
| 815 |
# Create figure
|