import streamlit as st import numpy as np import pandas as pd import pymongo import os import unicodedata st.set_page_config(layout="wide") @st.cache_resource def init_conn(): # Try to get from environment variable first, fall back to secrets uri = os.getenv('MONGO_URI') if not uri: uri = st.secrets['mongo_uri'] client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=500000) db = client["PGA_Database"] return db db = init_conn() dk_player_url = 'https://docs.google.com/spreadsheets/d/1lMLxWdvCnOFBtG9dhM0zv2USuxZbkogI_2jnxFfQVVs/edit#gid=1828092624' CSV_URL = 'https://docs.google.com/spreadsheets/d/1lMLxWdvCnOFBtG9dhM0zv2USuxZbkogI_2jnxFfQVVs/edit#gid=1828092624' player_roo_format = {'Cut_Odds': '{:.2%}', 'Top_finish': '{:.2%}','Top_5_finish': '{:.2%}', 'Top_10_finish': '{:.2%}', '100+%': '{:.2%}', '5x%': '{:.2%}', '6x%': '{:.2%}', '7x%': '{:.2%}', '10x%': '{:.2%}', '11x%': '{:.2%}', '12x%': '{:.2%}','LevX': '{:.2%}'} dk_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own'] fd_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own'] st.markdown(""" """, unsafe_allow_html=True) @st.cache_resource(ttl = 60) def init_baselines(): collection = db["PGA_Placement_Rates"] cursor = collection.find() placement_frame = pd.DataFrame(cursor) collection = db["PGA_Range_of_Outcomes"] cursor = collection.find() player_frame = pd.DataFrame(cursor) player_frame['Cut_Odds'] = player_frame['Player'].map(placement_frame.set_index('Player')['Cut_Odds']) player_frame = player_frame[['Player', 'Cut_Odds'] + [col for col in player_frame.columns if col not in ['Player', 'Cut_Odds']]] timestamp = player_frame['Timestamp'][0] roo_data = player_frame.drop(columns=['_id', 'index', 'Timestamp']) roo_data['Salary'] = roo_data['Salary'].astype(int) collection = db["PGA_SD_ROO"] cursor = collection.find() player_frame = pd.DataFrame(cursor) sd_roo_data = player_frame.drop(columns=['_id', 'index']) sd_roo_data['Salary'] = sd_roo_data['Salary'].astype(int) sd_roo_data = player_frame.drop(columns=['_id', 'index']) sd_roo_data['Salary'] = sd_roo_data['Salary'].astype(int) return roo_data, sd_roo_data, timestamp @st.cache_data(ttl = 60) def init_DK_lineups(type): if type == 'Regular': collection = db['PGA_DK_Seed_Frame_Name_Map'] elif type == 'Showdown': collection = db['PGA_DK_SD_Seed_Frame_Name_Map'] cursor = collection.find() raw_data = pd.DataFrame(list(cursor)) names_dict = dict(zip(raw_data['key'], raw_data['value'])) if type == 'Regular': collection = db["PGA_DK_Seed_Frame"] elif type == 'Showdown': collection = db["PGA_DK_SD_Seed_Frame"] cursor = collection.find().limit(10000) raw_display = pd.DataFrame(list(cursor)) raw_display = raw_display[['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own']] dict_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6'] for col in dict_columns: raw_display[col] = raw_display[col].map(names_dict) DK_seed = raw_display.to_numpy() return DK_seed @st.cache_data(ttl = 60) def init_FD_lineups(type): if type == 'Regular': collection = db['PGA_FD_Seed_Frame_Name_Map'] elif type == 'Showdown': collection = db['PGA_DK_SD_Seed_Frame_Name_Map'] cursor = collection.find() raw_data = pd.DataFrame(list(cursor)) names_dict = dict(zip(raw_data['key'], raw_data['value'])) if type == 'Regular': collection = db["PGA_FD_Seed_Frame"] elif type == 'Showdown': collection = db["PGA_DK_SD_Seed_Frame"] cursor = collection.find().limit(10000) raw_display = pd.DataFrame(list(cursor)) raw_display = raw_display[['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own']] dict_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6'] for col in dict_columns: raw_display[col] = raw_display[col].map(names_dict) FD_seed = raw_display.to_numpy() return FD_seed def normalize_special_characters(text): """Convert accented characters to their ASCII equivalents""" if pd.isna(text): return text # Normalize unicode characters to their closest ASCII equivalents normalized = unicodedata.normalize('NFKD', str(text)) # Remove diacritics (accents, umlauts, etc.) ascii_text = ''.join(c for c in normalized if not unicodedata.combining(c)) return ascii_text def convert_df_to_csv(df): df_clean = df.copy() for col in df_clean.columns: if df_clean[col].dtype == 'object': df_clean[col] = df_clean[col].apply(normalize_special_characters) return df_clean.to_csv(index=False).encode('utf-8') @st.cache_data def convert_df(array): array = pd.DataFrame(array, columns=column_names) # Normalize special characters in the dataframe before export for col in array.columns: if array[col].dtype == 'object': array[col] = array[col].apply(normalize_special_characters) return array.to_csv(index=False).encode('utf-8') @st.cache_data def convert_pm_df(array): array = pd.DataFrame(array) # Normalize special characters in the dataframe before export for col in array.columns: if array[col].dtype == 'object': array[col] = array[col].apply(normalize_special_characters) return array.to_csv(index=False).encode('utf-8') roo_data, sd_roo_data, timestamp = init_baselines() dk_id_dict = dict(zip(roo_data[roo_data['Site'] == 'Draftkings']['Player'], roo_data[roo_data['Site'] == 'Draftkings']['player_id'])) dk_id_dict_sd = dict(zip(sd_roo_data['Player'], sd_roo_data['player_id'])) fd_id_dict = dict(zip(roo_data[roo_data['Site'] == 'Fanduel']['Player'], roo_data[roo_data['Site'] == 'Fanduel']['player_id'])) fd_id_dict_sd = dk_id_dict_sd hold_display = roo_data app_load_reset_column, app_view_site_column = st.columns([1, 9]) with app_load_reset_column: if st.button("Load/Reset Data", key='reset_data_button'): st.cache_data.clear() roo_data, sd_roo_data, timestamp = init_baselines() dk_id_dict = dict(zip(roo_data[roo_data['Site'] == 'Draftkings']['Player'], roo_data[roo_data['Site'] == 'Draftkings']['player_id'])) dk_id_dict_sd = dict(zip(sd_roo_data['Player'], sd_roo_data['player_id'])) fd_id_dict = dict(zip(roo_data[roo_data['Site'] == 'Fanduel']['Player'], roo_data[roo_data['Site'] == 'Fanduel']['player_id'])) fd_id_dict_sd = dk_id_dict_sd dk_lineups = init_DK_lineups('Regular') fd_lineups = init_FD_lineups('Regular') hold_display = roo_data for key in st.session_state.keys(): del st.session_state[key] with app_view_site_column: with st.container(): app_view_column, app_site_column = st.columns([3, 3]) with app_view_column: view_var = st.selectbox("Select view", ["Simple", "Advanced"], key='view_selectbox') with app_site_column: site_var = st.selectbox("What site do you want to view?", ('Draftkings', 'Fanduel'), key='site_selectbox') selected_tab = st.segmented_control( "Select Tab", options=["Player ROO", "Optimals"], selection_mode='single', default='Player ROO', width='stretch', label_visibility='collapsed', key='tab_selector' ) if selected_tab == "Player ROO": with st.expander("Info and Filters"): if st.button("Reset Data", key='reset1'): st.cache_data.clear() roo_data, sd_roo_data, timestamp = init_baselines() dk_id_dict = dict(zip(roo_data[roo_data['Site'] == 'Draftkings']['Player'], roo_data[roo_data['Site'] == 'Draftkings']['player_id'])) dk_id_dict_sd = dict(zip(sd_roo_data['Player'], sd_roo_data['player_id'])) fd_id_dict = dict(zip(roo_data[roo_data['Site'] == 'Fanduel']['Player'], roo_data[roo_data['Site'] == 'Fanduel']['player_id'])) fd_id_dict_sd = dk_id_dict_sd dk_lineups = init_DK_lineups('Regular') fd_lineups = init_FD_lineups('Regular') hold_display = roo_data for key in st.session_state.keys(): del st.session_state[key] st.write(timestamp) type_var = st.radio("Select a Type", ["Full Slate", "Showdown"]) if type_var == "Full Slate": display = hold_display[hold_display['Site'] == site_var] display = display.drop_duplicates(subset=['Player']) elif type_var == "Showdown": display = sd_roo_data display = display.drop_duplicates(subset=['Player']) export_data = display.copy() export_data_pm = display[['Player', 'Salary', 'Median', 'Own']] export_data_pm['Position'] = 'G' export_data_pm['Team'] = 'Golf' export_data_pm['captain ownership'] = '' export_data_pm = export_data_pm.rename(columns={'Own': 'ownership', 'Median': 'median', 'Player': 'player_names', 'Position': 'position', 'Team': 'team', 'Salary': 'salary'}) reg_dl_col, pm_dl_col, blank_col = st.columns([2, 2, 6]) with reg_dl_col: st.download_button( label="Export ROO (Regular)", data=convert_df_to_csv(export_data), file_name='PGA_ROO_export.csv', mime='text/csv', ) with pm_dl_col: st.download_button( label="Export ROO (Portfolio Manager)", data=convert_df_to_csv(export_data_pm), file_name='PGA_ROO_export.csv', mime='text/csv', ) with st.container(): if view_var == "Simple": if type_var == "Full Slate": display = display[['Player', 'Cut_Odds', 'Salary', 'Median', '10x%', 'Own']] display = display.set_index('Player') elif type_var == "Showdown": display = display[['Player', 'Salary', 'Median', '5x%', 'Own']] display = display.set_index('Player') st.dataframe(display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height=750, use_container_width = True) elif view_var == "Advanced": display = display display = display.set_index('Player') st.dataframe(display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(player_roo_format, precision=2), height=750, use_container_width = True) if selected_tab == "Optimals": with st.expander("Info and Filters"): if st.button("Load/Reset Data", key='reset2'): st.cache_data.clear() roo_data, sd_roo_data, timestamp = init_baselines() dk_id_dict = dict(zip(roo_data[roo_data['Site'] == 'Draftkings']['Player'], roo_data[roo_data['Site'] == 'Draftkings']['player_id'])) dk_id_dict_sd = dict(zip(sd_roo_data['Player'], sd_roo_data['player_id'])) fd_id_dict = dict(zip(roo_data[roo_data['Site'] == 'Fanduel']['Player'], roo_data[roo_data['Site'] == 'Fanduel']['player_id'])) fd_id_dict_sd = dk_id_dict_sd hold_display = roo_data dk_lineups = init_DK_lineups('Regular') fd_lineups = init_FD_lineups('Regular') t_stamp = f"Last Update: " + str(timestamp) + f" CST" for key in st.session_state.keys(): del st.session_state[key] col1, col2, col3, col4 = st.columns(4) with col1: slate_var1 = st.radio("Which data are you loading?", ('Regular', 'Showdown')) if slate_var1 == 'Regular': if site_var == 'Draftkings': dk_lineups = init_DK_lineups('Regular') id_dict = dk_id_dict.copy() elif site_var == 'Fanduel': fd_lineups = init_FD_lineups('Regular') id_dict = fd_id_dict.copy() elif slate_var1 == 'Showdown': if site_var == 'Draftkings': dk_lineups = init_DK_lineups('Showdown') id_dict_sd = dk_id_dict_sd.copy() elif site_var == 'Fanduel': fd_lineups = init_FD_lineups('Showdown') id_dict_sd = fd_id_dict_sd.copy() if slate_var1 == 'Regular': raw_baselines = roo_data elif slate_var1 == 'Showdown': raw_baselines = sd_roo_data if site_var == 'Draftkings': if slate_var1 == 'Regular': ROO_slice = raw_baselines[raw_baselines['Site'] == 'Draftkings'] player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary'])) elif slate_var1 == 'Showdown': player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary'])) # Get the minimum and maximum ownership values from dk_lineups min_own = np.min(dk_lineups[:,8]) max_own = np.max(dk_lineups[:,8]) column_names = dk_columns elif site_var == 'Fanduel': raw_baselines = hold_display if slate_var1 == 'Regular': ROO_slice = raw_baselines[raw_baselines['Site'] == 'Fanduel'] player_salaries = dict(zip(ROO_slice['Player'], ROO_slice['Salary'])) elif slate_var1 == 'Showdown': player_salaries = dict(zip(raw_baselines['Player'], raw_baselines['Salary'])) min_own = np.min(fd_lineups[:,8]) max_own = np.max(fd_lineups[:,8]) column_names = fd_columns with col2: lineup_num_var = st.number_input("How many lineups do you want to display?", min_value=1, max_value=1000, value=150, step=1) with col3: player_var1 = st.radio("Do you want a frame with specific Players?", ('Full Slate', 'Specific Players'), key='player_var1') if player_var1 == 'Specific Players': player_var2 = st.multiselect('Which players do you want?', options = raw_baselines['Player'].unique()) elif player_var1 == 'Full Slate': player_var2 = raw_baselines.Player.values.tolist() with col4: if site_var == 'Draftkings': salary_min_var = st.number_input("Minimum salary used", min_value = 0, max_value = 50000, value = 49000, step = 100, key = 'salary_min_var') salary_max_var = st.number_input("Maximum salary used", min_value = 0, max_value = 50000, value = 50000, step = 100, key = 'salary_max_var') elif site_var == 'Fanduel': salary_min_var = st.number_input("Minimum salary used", min_value = 0, max_value = 60000, value = 59000, step = 100, key = 'salary_min_var') salary_max_var = st.number_input("Maximum salary used", min_value = 0, max_value = 60000, value = 60000, step = 100, key = 'salary_max_var') reg_dl_col, filtered_dl_col, blank_dl_col = st.columns([2, 2, 6]) with reg_dl_col: if st.button("Prepare full data export", key='data_export'): name_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names) data_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names) if site_var == 'Draftkings': if slate_var1 == 'Regular': map_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6'] elif slate_var1 == 'Showdown': map_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6'] elif site_var == 'Fanduel': if slate_var1 == 'Regular': map_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6'] elif slate_var1 == 'Showdown': map_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6'] for col_idx in map_columns: if slate_var1 == 'Regular': data_export[col_idx] = data_export[col_idx].map(id_dict) elif slate_var1 == 'Showdown': data_export[col_idx] = data_export[col_idx].map(id_dict_sd) pm_name_export = name_export.drop(columns=['salary', 'proj', 'Own'], axis=1) pm_data_export = data_export.drop(columns=['salary', 'proj', 'Own'], axis=1) reg_opt_col, pm_opt_col = st.columns(2) with reg_opt_col: st.download_button( label="Export optimals set (IDs)", data=convert_df(data_export), file_name='PGA_optimals_export.csv', mime='text/csv', ) st.download_button( label="Export optimals set (Names)", data=convert_df(name_export), file_name='PGA_optimals_export.csv', mime='text/csv', ) with pm_opt_col: st.download_button( label="Portfolio Manager Export (IDs)", data=convert_pm_df(pm_data_export), file_name='PGA_optimals_export.csv', mime='text/csv', ) st.download_button( label="Portfolio Manager Export (Names)", data=convert_pm_df(pm_name_export), file_name='PGA_optimals_export.csv', mime='text/csv', ) with filtered_dl_col: if st.button("Prepare full data export (Filtered)", key='data_export_filtered'): name_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names) data_export = pd.DataFrame(st.session_state.working_seed.copy(), columns=column_names) if site_var == 'Draftkings': if slate_var1 == 'Regular': map_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6'] elif slate_var1 == 'Showdown': map_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6'] elif site_var == 'Fanduel': if slate_var1 == 'Regular': map_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6'] elif slate_var1 == 'Showdown': map_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6'] for col_idx in map_columns: if slate_var1 == 'Regular': data_export[col_idx] = data_export[col_idx].map(id_dict) elif slate_var1 == 'Showdown': data_export[col_idx] = data_export[col_idx].map(id_dict_sd) data_export = data_export[data_export['salary'] >= salary_min_var] data_export = data_export[data_export['salary'] <= salary_max_var] name_export = name_export[name_export['salary'] >= salary_min_var] name_export = name_export[name_export['salary'] <= salary_max_var] pm_name_export = name_export.drop(columns=['salary', 'proj', 'Own'], axis=1) pm_data_export = data_export.drop(columns=['salary', 'proj', 'Own'], axis=1) reg_opt_col, pm_opt_col = st.columns(2) with reg_opt_col: st.download_button( label="Export optimals set (IDs)", data=convert_df(data_export), file_name='PGA_optimals_export.csv', mime='text/csv', ) st.download_button( label="Export optimals set (Names)", data=convert_df(name_export), file_name='PGA_optimals_export.csv', mime='text/csv', ) with pm_opt_col: st.download_button( label="Portfolio Manager Export (IDs)", data=convert_pm_df(pm_data_export), file_name='PGA_optimals_export.csv', mime='text/csv', ) st.download_button( label="Portfolio Manager Export (Names)", data=convert_pm_df(pm_name_export), file_name='PGA_optimals_export.csv', mime='text/csv', ) if site_var == 'Draftkings': if 'working_seed' in st.session_state: st.session_state.working_seed = st.session_state.working_seed if player_var1 == 'Specific Players': st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)] elif player_var1 == 'Full Slate': st.session_state.working_seed = dk_lineups.copy() st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names) elif 'working_seed' not in st.session_state: st.session_state.working_seed = dk_lineups.copy() st.session_state.working_seed = st.session_state.working_seed if player_var1 == 'Specific Players': st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)] elif player_var1 == 'Full Slate': st.session_state.working_seed = dk_lineups.copy() st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names) elif site_var == 'Fanduel': if 'working_seed' in st.session_state: st.session_state.working_seed = st.session_state.working_seed if player_var1 == 'Specific Players': st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)] elif player_var1 == 'Full Slate': st.session_state.working_seed = fd_lineups.copy() st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names) elif 'working_seed' not in st.session_state: st.session_state.working_seed = fd_lineups.copy() st.session_state.working_seed = st.session_state.working_seed if player_var1 == 'Specific Players': st.session_state.working_seed = st.session_state.working_seed[np.equal.outer(st.session_state.working_seed, player_var2).any(axis=1).all(axis=1)] elif player_var1 == 'Full Slate': st.session_state.working_seed = fd_lineups.copy() st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names) export_file = st.session_state.data_export_display.copy() # if site_var1 == 'Draftkings': # for col_idx in range(6): # export_file.iloc[:, col_idx] = export_file.iloc[:, col_idx].map(id_dict) # elif site_var1 == 'Fanduel': # for col_idx in range(6): # export_file.iloc[:, col_idx] = export_file.iloc[:, col_idx].map(id_dict) with st.container(): if st.button("Reset Optimals", key='reset3'): for key in st.session_state.keys(): del st.session_state[key] if site_var == 'Draftkings': st.session_state.working_seed = dk_lineups.copy() elif site_var == 'Fanduel': st.session_state.working_seed = fd_lineups.copy() st.session_state.data_export_display = st.session_state.data_export_display[st.session_state.data_export_display['salary'].between(salary_min_var, salary_max_var)] if 'data_export_display' in st.session_state: 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) st.download_button( label="Export display optimals", data=convert_df(export_file), file_name='PGA_display_optimals.csv', mime='text/csv', ) with st.container(): if 'working_seed' in st.session_state: # Create a new dataframe with summary statistics if site_var == 'Draftkings': summary_df = pd.DataFrame({ 'Metric': ['Min', 'Average', 'Max', 'STDdev'], 'Salary': [ np.min(st.session_state.working_seed[:,6]), np.mean(st.session_state.working_seed[:,6]), np.max(st.session_state.working_seed[:,6]), np.std(st.session_state.working_seed[:,6]) ], 'Proj': [ np.min(st.session_state.working_seed[:,7]), np.mean(st.session_state.working_seed[:,7]), np.max(st.session_state.working_seed[:,7]), np.std(st.session_state.working_seed[:,7]) ], 'Own': [ np.min(st.session_state.working_seed[:,8]), np.mean(st.session_state.working_seed[:,8]), np.max(st.session_state.working_seed[:,8]), np.std(st.session_state.working_seed[:,8]) ] }) elif site_var == 'Fanduel': summary_df = pd.DataFrame({ 'Metric': ['Min', 'Average', 'Max', 'STDdev'], 'Salary': [ np.min(st.session_state.working_seed[:,6]), np.mean(st.session_state.working_seed[:,6]), np.max(st.session_state.working_seed[:,6]), np.std(st.session_state.working_seed[:,6]) ], 'Proj': [ np.min(st.session_state.working_seed[:,7]), np.mean(st.session_state.working_seed[:,7]), np.max(st.session_state.working_seed[:,7]), np.std(st.session_state.working_seed[:,7]) ], 'Own': [ np.min(st.session_state.working_seed[:,8]), np.mean(st.session_state.working_seed[:,8]), np.max(st.session_state.working_seed[:,8]), np.std(st.session_state.working_seed[:,8]) ] }) # Set the index of the summary dataframe as the "Metric" column summary_df = summary_df.set_index('Metric') # Display the summary dataframe st.subheader("Optimal Statistics") st.dataframe(summary_df.style.format({ 'Salary': '{:.2f}', 'Proj': '{:.2f}', 'Own': '{:.2f}' }).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own']), use_container_width=True) with st.container(): tab1, tab2 = st.tabs(["Display Frequency", "Seed Frame Frequency"]) with tab1: if 'data_export_display' in st.session_state: if site_var == 'Draftkings': player_columns = st.session_state.data_export_display.iloc[:, :6] elif site_var == 'Fanduel': player_columns = st.session_state.data_export_display.iloc[:, :6] # Flatten the DataFrame and count unique values value_counts = player_columns.values.flatten().tolist() value_counts = pd.Series(value_counts).value_counts() percentages = (value_counts / lineup_num_var * 100).round(2) # Create a DataFrame with the results summary_df = pd.DataFrame({ 'Player': value_counts.index, 'Frequency': value_counts.values, 'Percentage': percentages.values }) # Sort by frequency in descending order summary_df['Salary'] = summary_df['Player'].map(player_salaries) summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']] summary_df = summary_df.sort_values('Frequency', ascending=False) summary_df = summary_df.set_index('Player') # Display the table st.write("Player Frequency Table:") st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True) st.download_button( label="Export player frequency", data=convert_df_to_csv(summary_df), file_name='PGA_player_frequency.csv', mime='text/csv', ) with tab2: if 'working_seed' in st.session_state: if site_var == 'Draftkings': player_columns = st.session_state.working_seed[:, :6] elif site_var == 'Fanduel': player_columns = st.session_state.working_seed[:, :6] # Flatten the DataFrame and count unique values value_counts = player_columns.flatten().tolist() value_counts = pd.Series(value_counts).value_counts() percentages = (value_counts / len(st.session_state.working_seed) * 100).round(2) # Create a DataFrame with the results summary_df = pd.DataFrame({ 'Player': value_counts.index, 'Frequency': value_counts.values, 'Percentage': percentages.values }) # Sort by frequency in descending order summary_df['Salary'] = summary_df['Player'].map(player_salaries) summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']] summary_df = summary_df.sort_values('Frequency', ascending=False) summary_df = summary_df.set_index('Player') # Display the table st.write("Seed Frame Frequency Table:") st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True) st.download_button( label="Export seed frame frequency", data=convert_df_to_csv(summary_df), file_name='PGA_seed_frame_frequency.csv', mime='text/csv', )