PGA_DFS_ROO / src /streamlit_app.py
James McCool
Update Streamlit app styling and layout by modifying tab and button styles for improved visual consistency. Adjust column layout for data loading options, enhancing user experience and interface clarity.
ada64ff
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("""
<style>
/* Tab styling */
.stElementContainer [data-baseweb="button-group"] {
gap: 8px;
padding: 4px;
}
.stElementContainer [kind="segmented_control"] {
height: 45px;
white-space: pre-wrap;
background-color: #DAA520;
color: white;
border-radius: 10px;
gap: 1px;
padding: 10px 20px;
font-weight: bold;
transition: all 0.3s ease;
}
.stElementContainer [kind="segmented_controlActive"] {
height: 50px;
background-color: #DAA520;
border: 3px solid #FFD700;
color: white;
}
.stElementContainer [kind="segmented_control"]:hover {
background-color: #FFD700;
cursor: pointer;
}
div[data-baseweb="select"] > div {
background-color: #DAA520;
color: white;
}
</style>""", 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',
)