James McCool commited on
Commit
68cf021
·
1 Parent(s): 64db329

Refactor baseline initialization to include player ID mappings for Draftkings and Fanduel. Update scoring percentage calculations to incorporate team ownership data for hitters, and enhance data export functionality to allow for exporting both player IDs and names.

Browse files
Files changed (1) hide show
  1. app.py +55 -33
app.py CHANGED
@@ -26,7 +26,6 @@ player_roo_format = {'Top_finish': '{:.2%}','Top_5_finish': '{:.2%}', 'Top_10_fi
26
  dk_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
27
  fd_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
28
 
29
-
30
  @st.cache_resource(ttl = 60)
31
  def init_baselines():
32
  collection = db["Player_Range_Of_Outcomes"]
@@ -37,7 +36,9 @@ def init_baselines():
37
  roo_data['Salary'] = roo_data['Salary'].astype(int)
38
 
39
  dk_roo = roo_data[roo_data['Site'] == 'Draftkings']
 
40
  fd_roo = roo_data[roo_data['Site'] == 'Fanduel']
 
41
 
42
  collection = db["Player_SD_Range_Of_Outcomes"]
43
  cursor = collection.find()
@@ -55,22 +56,8 @@ def init_baselines():
55
  scoring_percentages['8+ runs'] = scoring_percentages['8+ runs'].replace('%', '', regex=True).astype(float)
56
  scoring_percentages['Win Percentage'] = scoring_percentages['Win Percentage'].replace('%', '', regex=True).astype(float)
57
  scoring_percentages['Top Score'] = scoring_percentages['Top Score'].replace('', np.nan).astype(float)
58
- dk_hitters_only = dk_roo[dk_roo['pos_group'] != 'Pitchers']
59
- dk_hitters_only = dk_hitters_only.replace('CWS', 'CHW')
60
- dk_team_ownership = dk_hitters_only.groupby('Team')['Own%'].sum().reset_index()
61
- fd_hitters_only = fd_roo[fd_roo['pos_group'] != 'Pitchers']
62
- fd_hitters_only = fd_hitters_only.replace('CWS', 'CHW')
63
- fd_team_ownership = fd_hitters_only.groupby('Team')['Own%'].sum().reset_index()
64
- scoring_percentages = scoring_percentages.merge(dk_team_ownership, left_on='Names', right_on='Team', how='left')
65
- scoring_percentages.rename(columns={'Own%': 'DK Own%'}, inplace=True)
66
- scoring_percentages.drop('Team', axis=1, inplace=True)
67
- scoring_percentages = scoring_percentages.merge(fd_team_ownership, left_on='Names', right_on='Team', how='left')
68
- scoring_percentages.rename(columns={'Own%': 'FD Own%'}, inplace=True)
69
- scoring_percentages.drop('Team', axis=1, inplace=True)
70
- scoring_percentages['DK LevX'] = scoring_percentages['Top Score'].rank(pct=True).astype(float) - scoring_percentages['DK Own%'].rank(pct=True).astype(float)
71
- scoring_percentages['FD LevX'] = scoring_percentages['Top Score'].rank(pct=True).astype(float) - scoring_percentages['FD Own%'].rank(pct=True).astype(float)
72
 
73
- return roo_data, sd_roo_data, scoring_percentages, dk_roo, fd_roo
74
 
75
  @st.cache_data(ttl = 60)
76
  def init_DK_lineups(type_var, slate_var):
@@ -226,7 +213,7 @@ col1, col2 = st.columns([1, 9])
226
  with col1:
227
  if st.button("Load/Reset Data", key='reset'):
228
  st.cache_data.clear()
229
- roo_data, sd_roo_data, scoring_percentages, dk_roo, fd_roo = init_baselines()
230
  hold_display = roo_data
231
  dk_lineups = init_DK_lineups('Regular', 'Main')
232
  fd_lineups = init_FD_lineups('Regular', 'Main')
@@ -243,7 +230,7 @@ with col2:
243
 
244
  tab1, tab2, tab3 = st.tabs(["Scoring Percentages", "Player ROO", "Optimals"])
245
 
246
- roo_data, sd_roo_data, scoring_percentages, dk_roo, fd_roo = init_baselines()
247
  hold_display = roo_data
248
 
249
  with tab1:
@@ -258,6 +245,23 @@ with tab1:
258
  elif slate_var1 != 'Main Slate':
259
  pass
260
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
261
  scoring_percentages = scoring_percentages.sort_values(by='8+ runs', ascending=False)
262
  scoring_percentages = scoring_percentages.drop('Slate', axis=1)
263
 
@@ -407,19 +411,28 @@ with tab3:
407
  player_var2 = raw_baselines.Player.values.tolist()
408
 
409
  if st.button("Prepare data export", key='data_export'):
410
- data_export = st.session_state.working_seed.copy()
411
- # if site_var == 'Draftkings':
412
- # for col_idx in range(6):
413
- # data_export[:, col_idx] = np.array([id_dict.get(player, player) for player in data_export[:, col_idx]])
414
- # elif site_var == 'Fanduel':
415
- # for col_idx in range(6):
416
- # data_export[:, col_idx] = np.array([id_dict.get(player, player) for player in data_export[:, col_idx]])
 
 
 
417
  st.download_button(
418
- label="Export optimals set",
419
  data=convert_df(data_export),
420
  file_name='MLB_optimals_export.csv',
421
  mime='text/csv',
422
  )
 
 
 
 
 
 
423
 
424
  if site_var == 'Draftkings':
425
  if 'working_seed' in st.session_state:
@@ -456,12 +469,15 @@ with tab3:
456
  st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
457
 
458
  export_file = st.session_state.data_export_display.copy()
459
- # if site_var == 'Draftkings':
460
- # for col_idx in range(6):
461
- # export_file.iloc[:, col_idx] = export_file.iloc[:, col_idx].map(id_dict)
462
- # elif site_var == 'Fanduel':
463
- # for col_idx in range(6):
464
- # export_file.iloc[:, col_idx] = export_file.iloc[:, col_idx].map(id_dict)
 
 
 
465
 
466
  with st.container():
467
  if st.button("Reset Optimals", key='reset3'):
@@ -474,11 +490,17 @@ with tab3:
474
  if 'data_export_display' in st.session_state:
475
  st.dataframe(st.session_state.data_export_display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height=500, use_container_width = True)
476
  st.download_button(
477
- label="Export display optimals",
478
  data=convert_df(export_file),
479
  file_name='MLB_display_optimals.csv',
480
  mime='text/csv',
481
  )
 
 
 
 
 
 
482
 
483
  with st.container():
484
  if 'working_seed' in st.session_state:
 
26
  dk_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
27
  fd_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']
28
 
 
29
  @st.cache_resource(ttl = 60)
30
  def init_baselines():
31
  collection = db["Player_Range_Of_Outcomes"]
 
36
  roo_data['Salary'] = roo_data['Salary'].astype(int)
37
 
38
  dk_roo = roo_data[roo_data['Site'] == 'Draftkings']
39
+ dk_id_map = dict(zip(dk_roo['Player'], dk_roo['player_ID']))
40
  fd_roo = roo_data[roo_data['Site'] == 'Fanduel']
41
+ fd_id_map = dict(zip(fd_roo['Player'], fd_roo['player_ID']))
42
 
43
  collection = db["Player_SD_Range_Of_Outcomes"]
44
  cursor = collection.find()
 
56
  scoring_percentages['8+ runs'] = scoring_percentages['8+ runs'].replace('%', '', regex=True).astype(float)
57
  scoring_percentages['Win Percentage'] = scoring_percentages['Win Percentage'].replace('%', '', regex=True).astype(float)
58
  scoring_percentages['Top Score'] = scoring_percentages['Top Score'].replace('', np.nan).astype(float)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
 
60
+ return roo_data, sd_roo_data, scoring_percentages, dk_roo, fd_roo, dk_id_map, fd_id_map
61
 
62
  @st.cache_data(ttl = 60)
63
  def init_DK_lineups(type_var, slate_var):
 
213
  with col1:
214
  if st.button("Load/Reset Data", key='reset'):
215
  st.cache_data.clear()
216
+ roo_data, sd_roo_data, scoring_percentages, dk_roo, fd_roo, dk_id_map, fd_id_map = init_baselines()
217
  hold_display = roo_data
218
  dk_lineups = init_DK_lineups('Regular', 'Main')
219
  fd_lineups = init_FD_lineups('Regular', 'Main')
 
230
 
231
  tab1, tab2, tab3 = st.tabs(["Scoring Percentages", "Player ROO", "Optimals"])
232
 
233
+ roo_data, sd_roo_data, scoring_percentages, dk_roo, fd_roo, dk_id_map, fd_id_map = init_baselines()
234
  hold_display = roo_data
235
 
236
  with tab1:
 
245
  elif slate_var1 != 'Main Slate':
246
  pass
247
 
248
+ dk_hitters_only = dk_roo[dk_roo['pos_group'] != 'Pitchers']
249
+ dk_hitters_only = dk_hitters_only[dk_hitters_only['Slate'] == 'main_slate']
250
+ dk_hitters_only = dk_hitters_only.replace('CWS', 'CHW')
251
+ dk_team_ownership = dk_hitters_only.groupby('Team')['Own%'].sum().reset_index()
252
+ fd_hitters_only = fd_roo[fd_roo['pos_group'] != 'Pitchers']
253
+ fd_hitters_only = fd_hitters_only[fd_hitters_only['Slate'] == 'main_slate']
254
+ fd_hitters_only = fd_hitters_only.replace('CWS', 'CHW')
255
+ fd_team_ownership = fd_hitters_only.groupby('Team')['Own%'].sum().reset_index()
256
+ scoring_percentages = scoring_percentages.merge(dk_team_ownership, left_on='Names', right_on='Team', how='left')
257
+ scoring_percentages.rename(columns={'Own%': 'DK Own%'}, inplace=True)
258
+ scoring_percentages.drop('Team', axis=1, inplace=True)
259
+ scoring_percentages = scoring_percentages.merge(fd_team_ownership, left_on='Names', right_on='Team', how='left')
260
+ scoring_percentages.rename(columns={'Own%': 'FD Own%'}, inplace=True)
261
+ scoring_percentages.drop('Team', axis=1, inplace=True)
262
+ scoring_percentages['DK LevX'] = scoring_percentages['Top Score'].rank(pct=True).astype(float) - scoring_percentages['DK Own%'].rank(pct=True).astype(float)
263
+ scoring_percentages['FD LevX'] = scoring_percentages['Top Score'].rank(pct=True).astype(float) - scoring_percentages['FD Own%'].rank(pct=True).astype(float)
264
+
265
  scoring_percentages = scoring_percentages.sort_values(by='8+ runs', ascending=False)
266
  scoring_percentages = scoring_percentages.drop('Slate', axis=1)
267
 
 
411
  player_var2 = raw_baselines.Player.values.tolist()
412
 
413
  if st.button("Prepare data export", key='data_export'):
414
+ name_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
415
+ data_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names)
416
+ if site_var == 'Draftkings':
417
+ map_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
418
+ for col_idx in map_columns:
419
+ data_export[col_idx] = data_export[col_idx].map(dk_id_map)
420
+ elif site_var == 'Fanduel':
421
+ map_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL']
422
+ for col_idx in map_columns:
423
+ data_export[col_idx] = data_export[col_idx].map(fd_id_map)
424
  st.download_button(
425
+ label="Export optimals set (IDs)",
426
  data=convert_df(data_export),
427
  file_name='MLB_optimals_export.csv',
428
  mime='text/csv',
429
  )
430
+ st.download_button(
431
+ label="Export optimals set (Names)",
432
+ data=convert_df(name_export),
433
+ file_name='MLB_optimals_export.csv',
434
+ mime='text/csv',
435
+ )
436
 
437
  if site_var == 'Draftkings':
438
  if 'working_seed' in st.session_state:
 
469
  st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
470
 
471
  export_file = st.session_state.data_export_display.copy()
472
+ name_export = st.session_state.data_export_display.copy()
473
+ if site_var == 'Draftkings':
474
+ map_columns = ['SP1', 'SP2', 'C', '1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3']
475
+ for col_idx in map_columns:
476
+ export_file[col_idx] = export_file[col_idx].map(dk_id_map)
477
+ elif site_var == 'Fanduel':
478
+ map_columns = ['P', 'C_1B', '2B', '3B', 'SS', 'OF1', 'OF2', 'OF3', 'UTIL']
479
+ for col_idx in map_columns:
480
+ export_file[col_idx] = export_file[col_idx].map(fd_id_map)
481
 
482
  with st.container():
483
  if st.button("Reset Optimals", key='reset3'):
 
490
  if 'data_export_display' in st.session_state:
491
  st.dataframe(st.session_state.data_export_display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), height=500, use_container_width = True)
492
  st.download_button(
493
+ label="Export display optimals (IDs)",
494
  data=convert_df(export_file),
495
  file_name='MLB_display_optimals.csv',
496
  mime='text/csv',
497
  )
498
+ st.download_button(
499
+ label="Export display optimals (Names)",
500
+ data=convert_df(name_export),
501
+ file_name='MLB_display_optimals.csv',
502
+ mime='text/csv',
503
+ )
504
 
505
  with st.container():
506
  if 'working_seed' in st.session_state: