MMA_DFS_ROO / src /streamlit_app.py
James McCool
removed last 'Site' call
3d2841a
import streamlit as st
import numpy as np
import pandas as pd
import pymongo
import os
import unicodedata
from database import db
st.set_page_config(layout="wide")
player_roo_format = {'Top_finish': '{:.2%}','Top_5_finish': '{:.2%}', 'Top_10_finish': '{:.2%}', '100+%': '{:.2%}', '10x%': '{:.2%}', '11x%': '{:.2%}', '12x%': '{:.2%}'}
dk_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own']
fd_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own']
### I should probably not have this be messy in terms of site declarations but eh
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["Player_Level_ROO"]
cursor = collection.find()
player_frame = pd.DataFrame(cursor)
roo_data = player_frame.drop(columns=['_id'])
roo_data['Salary'] = roo_data['Salary'].astype(int)
return roo_data
@st.cache_data(ttl = 60)
def init_DK_lineups(type):
if type == 'Regular':
collection = db['DK_MMA_name_map']
elif type == 'Showdown':
collection = db['DK_SD_MMA_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["DK_MMA_seed_frame_Main Slate"]
elif type == 'Showdown':
collection = db["DK_SD_MMA_seed_frame_Main Slate"]
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['FD_MMA_name_map']
elif type == 'Showdown':
collection = db['FD_SD_MMA_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["FD_MMA_seed_frame_Main Slate"]
elif type == 'Showdown':
collection = db["FD_SD_MMA_seed_frame_Main Slate"]
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 = init_baselines()
dk_id_dict = dict(zip(roo_data['Player'], roo_data['player_id']))
dk_id_dict_sd = {}
fd_id_dict = dict(zip(roo_data['Player'], roo_data['player_id']))
fd_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 = init_baselines()
dk_id_dict = dict(zip(roo_data['Player'], roo_data['player_id']))
dk_id_dict_sd = {}
fd_id_dict = dict(zip(roo_data['Player'], roo_data['player_id']))
fd_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'), 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 = init_baselines()
dk_id_dict = dict(zip(roo_data['Player'], roo_data['player_id']))
dk_id_dict_sd = {}
fd_id_dict = dict(zip(roo_data['Player'], roo_data['player_id']))
fd_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]
type_var = st.radio("Select a Type", ["Full Slate"])
if type_var == "Full Slate":
display = hold_display
display = display.drop_duplicates(subset=['Player'])
elif type_var == "Showdown":
display = pd.DataFrame()
display = display.drop_duplicates(subset=['Player'])
export_data = display.copy()
export_data_pm = display[['Player', 'Salary', 'Median', 'Own']]
export_data_pm['Position'] = 'FLEX'
export_data_pm['Team'] = 'MMA'
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='MMA_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='MMA_ROO_export.csv',
mime='text/csv',
)
with st.container():
if view_var == "Simple":
if type_var == "Full Slate":
display = display[['Player', '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 = init_baselines()
dk_id_dict = dict(zip(roo_data['Player'], roo_data['player_id']))
dk_id_dict_sd = {}
fd_id_dict = dict(zip(roo_data['Player'], roo_data['player_id']))
fd_id_dict_sd = {}
hold_display = roo_data
dk_lineups = init_DK_lineups('Regular')
fd_lineups = init_FD_lineups('Regular')
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'))
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 = pd.DataFrame()
if site_var == 'Draftkings':
if slate_var1 == 'Regular':
ROO_slice = raw_baselines
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
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='MMA_optimals_export.csv',
mime='text/csv',
)
st.download_button(
label="Export optimals set (Names)",
data=convert_df(name_export),
file_name='MMA_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='MMA_optimals_export.csv',
mime='text/csv',
)
st.download_button(
label="Portfolio Manager Export (Names)",
data=convert_pm_df(pm_name_export),
file_name='MMA_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='MMA_optimals_export.csv',
mime='text/csv',
)
st.download_button(
label="Export optimals set (Names)",
data=convert_df(name_export),
file_name='MMA_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='MMA_optimals_export.csv',
mime='text/csv',
)
st.download_button(
label="Portfolio Manager Export (Names)",
data=convert_pm_df(pm_name_export),
file_name='MMA_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='MMA_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='MMA_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='MMA_seed_frame_frequency.csv',
mime='text/csv',
)