James McCool
Update init_baselines function in app.py to accept a slate variable, allowing dynamic filtering of player data based on the selected slate. Adjusted multiple instances throughout the code to ensure consistent data retrieval for both 'Main Slate' and 'Secondary Slate'. Additionally, refined sharp_split values for improved performance in simulations. This enhances flexibility and user experience in DraftKings and FanDuel simulations.
cf45400
import streamlit as st | |
st.set_page_config(layout="wide") | |
import numpy as np | |
import pandas as pd | |
import pymongo | |
import time | |
def init_conn(): | |
uri = st.secrets['mongo_uri'] | |
client = pymongo.MongoClient(uri, retryWrites=True, serverSelectionTimeoutMS=500000) | |
db = client["NFL_Database"] | |
return db | |
db = init_conn() | |
percentages_format = {'Exposure': '{:.2%}'} | |
freq_format = {'Exposure': '{:.2%}', 'Proj Own': '{:.2%}', 'Edge': '{:.2%}'} | |
dk_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'] | |
fd_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own'] | |
def init_DK_seed_frames(sharp_split): | |
collection = db['DK_NFL_name_map'] | |
cursor = collection.find() | |
raw_data = pd.DataFrame(list(cursor)) | |
names_dict = dict(zip(raw_data['key'], raw_data['value'])) | |
collection = db["DK_NFL_seed_frame"] | |
cursor = collection.find().limit(sharp_split) | |
raw_display = pd.DataFrame(list(cursor)) | |
raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']] | |
dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST'] | |
st.write("converting names") | |
for col in dict_columns: | |
raw_display[col] = raw_display[col].map(names_dict) | |
DK_seed = raw_display.to_numpy() | |
return DK_seed | |
def init_DK_Secondary_seed_frames(sharp_split): | |
collection = db['DK_NFL_Secondary_name_map'] | |
cursor = collection.find() | |
raw_data = pd.DataFrame(list(cursor)) | |
names_dict = dict(zip(raw_data['key'], raw_data['value'])) | |
collection = db["DK_NFL_Secondary_seed_frame"] | |
cursor = collection.find().limit(sharp_split) | |
raw_display = pd.DataFrame(list(cursor)) | |
raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']] | |
dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST'] | |
st.write("converting names") | |
for col in dict_columns: | |
raw_display[col] = raw_display[col].map(names_dict) | |
DK_seed = raw_display.to_numpy() | |
return DK_seed | |
def init_FD_seed_frames(sharp_split): | |
collection = db['FD_NFL_name_map'] | |
cursor = collection.find() | |
raw_data = pd.DataFrame(list(cursor)) | |
names_dict = dict(zip(raw_data['key'], raw_data['value'])) | |
collection = db["FD_NFL_seed_frame"] | |
cursor = collection.find().limit(sharp_split) | |
raw_display = pd.DataFrame(list(cursor)) | |
raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']] | |
dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST'] | |
st.write("converting names") | |
for col in dict_columns: | |
raw_display[col] = raw_display[col].map(names_dict) | |
FD_seed = raw_display.to_numpy() | |
return FD_seed | |
def init_FD_Secondary_seed_frames(sharp_split): | |
collection = db['FD_NFL_Secondary_name_map'] | |
cursor = collection.find() | |
raw_data = pd.DataFrame(list(cursor)) | |
names_dict = dict(zip(raw_data['key'], raw_data['value'])) | |
collection = db["FD_NFL_Secondary_seed_frame"] | |
cursor = collection.find().limit(sharp_split) | |
raw_display = pd.DataFrame(list(cursor)) | |
raw_display = raw_display[['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST', 'salary', 'proj', 'Team', 'Team_count', 'Secondary', 'Secondary_count', 'Own']] | |
dict_columns = ['QB', 'RB1', 'RB2', 'WR1', 'WR2', 'WR3', 'TE', 'FLEX', 'DST'] | |
st.write("converting names") | |
for col in dict_columns: | |
raw_display[col] = raw_display[col].map(names_dict) | |
FD_seed = raw_display.to_numpy() | |
return FD_seed | |
def init_baselines(slate_var): | |
collection = db["DK_NFL_ROO"] | |
cursor = collection.find() | |
raw_display = pd.DataFrame(list(cursor)) | |
raw_display = raw_display[raw_display['slate'] == slate_var] | |
raw_display = raw_display[raw_display['version'] == 'overall'] | |
dk_raw = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%', | |
'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_id', 'site']] | |
dk_raw['STDev'] = (dk_raw['Ceiling'] - dk_raw['Floor']) / 4 | |
collection = db["FD_NFL_ROO"] | |
cursor = collection.find() | |
raw_display = pd.DataFrame(list(cursor)) | |
raw_display = raw_display[raw_display['slate'] == slate_var] | |
raw_display = raw_display[raw_display['version'] == 'overall'] | |
fd_raw = raw_display[['Player', 'Position', 'Team', 'Opp', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '2x%', '3x%', '4x%', | |
'Own', 'Small_Field_Own', 'Large_Field_Own', 'Cash_Field_Own', 'CPT_Own', 'LevX', 'version', 'slate', 'timestamp', 'player_id', 'site']] | |
fd_raw['STDev'] = (fd_raw['Ceiling'] - fd_raw['Floor']) / 4 | |
return dk_raw, fd_raw | |
def convert_df(array): | |
array = pd.DataFrame(array, columns=column_names) | |
return array.to_csv().encode('utf-8') | |
def calculate_DK_value_frequencies(np_array): | |
unique, counts = np.unique(np_array[:, :9], return_counts=True) | |
frequencies = counts / len(np_array) # Normalize by the number of rows | |
combined_array = np.column_stack((unique, frequencies)) | |
return combined_array | |
def calculate_FD_value_frequencies(np_array): | |
unique, counts = np.unique(np_array[:, :9], return_counts=True) | |
frequencies = counts / len(np_array) # Normalize by the number of rows | |
combined_array = np.column_stack((unique, frequencies)) | |
return combined_array | |
def sim_contest(Sim_size, seed_frame, maps_dict, Contest_Size): | |
SimVar = 1 | |
Sim_Winners = [] | |
fp_array = seed_frame.copy() | |
# Pre-vectorize functions | |
vec_projection_map = np.vectorize(maps_dict['Projection_map'].__getitem__) | |
vec_stdev_map = np.vectorize(maps_dict['STDev_map'].__getitem__) | |
st.write('Simulating contest on frames') | |
while SimVar <= Sim_size: | |
fp_random = fp_array[np.random.choice(fp_array.shape[0], Contest_Size)] | |
sample_arrays1 = np.c_[ | |
fp_random, | |
np.sum(np.random.normal( | |
loc=vec_projection_map(fp_random[:, :-7]), | |
scale=vec_stdev_map(fp_random[:, :-7])), | |
axis=1) | |
] | |
sample_arrays = sample_arrays1 | |
final_array = sample_arrays[sample_arrays[:, 10].argsort()[::-1]] | |
best_lineup = final_array[final_array[:, -1].argsort(kind='stable')[::-1][:1]] | |
Sim_Winners.append(best_lineup) | |
SimVar += 1 | |
return Sim_Winners | |
tab1, tab2 = st.tabs(['Contest Sims', 'Data Export']) | |
with tab2: | |
col1, col2 = st.columns([1, 7]) | |
with col1: | |
if st.button("Load/Reset Data", key='reset1'): | |
st.cache_data.clear() | |
for key in st.session_state.keys(): | |
del st.session_state[key] | |
DK_seed = init_DK_seed_frames(10000) | |
FD_seed = init_FD_seed_frames(10000) | |
dk_raw, fd_raw = init_baselines('Main Slate') | |
dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id)) | |
fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id)) | |
slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate')) | |
site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel')) | |
sharp_split_var = st.number_input("How many lineups do you want?", value=10000, max_value=500000, min_value=10000, step=10000) | |
if site_var1 == 'Draftkings': | |
team_var1 = st.radio("Do you want a frame with specific teams?", ('Full Slate', 'Specific Teams'), key='team_var1') | |
if team_var1 == 'Specific Teams': | |
dk_raw, fd_raw = init_baselines('Main Slate') | |
team_var2 = st.multiselect('Which teams do you want?', options = dk_raw['Team'].unique()) | |
elif team_var1 == 'Full Slate': | |
dk_raw, fd_raw = init_baselines('Main Slate') | |
team_var2 = dk_raw.Team.values.tolist() | |
stack_var1 = st.radio("Do you want a frame with specific stack sizes?", ('Full Slate', 'Specific Stack Sizes'), key='stack_var1') | |
if stack_var1 == 'Specific Stack Sizes': | |
stack_var2 = st.multiselect('Which stack sizes do you want?', options = [5, 4, 3, 2, 1, 0]) | |
elif stack_var1 == 'Full Slate': | |
stack_var2 = [5, 4, 3, 2, 1, 0] | |
elif site_var1 == 'Fanduel': | |
team_var1 = st.radio("Do you want a frame with specific teams?", ('Full Slate', 'Specific Teams'), key='team_var1') | |
if team_var1 == 'Specific Teams': | |
dk_raw, fd_raw = init_baselines('Main Slate') | |
team_var2 = st.multiselect('Which teams do you want?', options = fd_raw['Team'].unique()) | |
elif team_var1 == 'Full Slate': | |
dk_raw, fd_raw = init_baselines('Main Slate') | |
team_var2 = fd_raw.Team.values.tolist() | |
stack_var1 = st.radio("Do you want a frame with specific stack sizes?", ('Full Slate', 'Specific Stack Sizes'), key='stack_var1') | |
if stack_var1 == 'Specific Stack Sizes': | |
stack_var2 = st.multiselect('Which stack sizes do you want?', options = [5, 4, 3, 2, 1, 0]) | |
elif stack_var1 == 'Full Slate': | |
stack_var2 = [5, 4, 3, 2, 1, 0] | |
if st.button("Prepare data export", key='data_export'): | |
if 'working_seed' in st.session_state: | |
st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)] | |
st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)] | |
elif 'working_seed' not in st.session_state: | |
if site_var1 == 'Draftkings': | |
if slate_var1 == 'Main Slate': | |
st.session_state.working_seed = init_DK_seed_frames(sharp_split_var) | |
dk_id_dict = dict(zip(st.session_state.working_seed.Player, st.session_state.working_seed.player_id)) | |
elif slate_var1 == 'Secondary Slate': | |
st.session_state.working_seed = init_DK_Secondary_seed_frames(sharp_split_var) | |
dk_id_dict = dict(zip(st.session_state.working_seed.Player, st.session_state.working_seed.player_id)) | |
raw_baselines = dk_raw | |
column_names = dk_columns | |
elif site_var1 == 'Fanduel': | |
if slate_var1 == 'Main Slate': | |
st.session_state.working_seed = init_FD_seed_frames(sharp_split_var) | |
fd_id_dict = dict(zip(st.session_state.working_seed.Player, st.session_state.working_seed.player_id)) | |
elif slate_var1 == 'Secondary Slate': | |
st.session_state.working_seed = init_FD_Secondary_seed_frames(sharp_split_var) | |
fd_id_dict = dict(zip(st.session_state.working_seed.Player, st.session_state.working_seed.player_id)) | |
raw_baselines = fd_raw | |
column_names = fd_columns | |
st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)] | |
st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)] | |
data_export = st.session_state.working_seed.copy() | |
for col in range(9): | |
data_export[:, col] = np.array([dk_id_dict.get(x, x) for x in data_export[:, col]]) | |
st.download_button( | |
label="Export optimals set", | |
data=convert_df(data_export), | |
file_name='NFL_optimals_export.csv', | |
mime='text/csv', | |
) | |
with col2: | |
if st.button("Load Data", key='load_data'): | |
if site_var1 == 'Draftkings': | |
if 'working_seed' in st.session_state: | |
st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)] | |
st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)] | |
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:1000], columns=column_names) | |
elif 'working_seed' not in st.session_state: | |
if slate_var1 == 'Main Slate': | |
st.session_state.working_seed = init_DK_seed_frames(sharp_split_var) | |
dk_id_dict = dict(zip(st.session_state.working_seed.Player, st.session_state.working_seed.player_id)) | |
dk_raw, fd_raw = init_baselines('Main Slate') | |
elif slate_var1 == 'Secondary Slate': | |
st.session_state.working_seed = init_DK_Secondary_seed_frames(sharp_split_var) | |
dk_id_dict = dict(zip(st.session_state.working_seed.Player, st.session_state.working_seed.player_id)) | |
dk_raw, fd_raw = init_baselines('Secondary Slate') | |
raw_baselines = dk_raw | |
column_names = dk_columns | |
st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)] | |
st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)] | |
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:1000], columns=column_names) | |
elif site_var1 == 'Fanduel': | |
if 'working_seed' in st.session_state: | |
st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)] | |
st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)] | |
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:1000], columns=column_names) | |
elif 'working_seed' not in st.session_state: | |
if slate_var1 == 'Main Slate': | |
st.session_state.working_seed = init_FD_seed_frames(sharp_split_var) | |
fd_id_dict = dict(zip(st.session_state.working_seed.Player, st.session_state.working_seed.player_id)) | |
dk_raw, fd_raw = init_baselines('Main Slate') | |
elif slate_var1 == 'Secondary Slate': | |
st.session_state.working_seed = init_FD_Secondary_seed_frames(sharp_split_var) | |
fd_id_dict = dict(zip(st.session_state.working_seed.Player, st.session_state.working_seed.player_id)) | |
dk_raw, fd_raw = init_baselines('Secondary Slate') | |
raw_baselines = fd_raw | |
column_names = fd_columns | |
st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 11], team_var2)] | |
st.session_state.working_seed = st.session_state.working_seed[np.isin(st.session_state.working_seed[:, 12], stack_var2)] | |
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:1000], columns=column_names) | |
with st.container(): | |
if 'data_export_display' in st.session_state: | |
st.dataframe(st.session_state.data_export_display.style.format(freq_format, precision=2), use_container_width = True) | |
with tab1: | |
col1, col2 = st.columns([1, 7]) | |
with col1: | |
if st.button("Load/Reset Data", key='reset2'): | |
st.cache_data.clear() | |
for key in st.session_state.keys(): | |
del st.session_state[key] | |
DK_seed = init_DK_seed_frames(10000) | |
FD_seed = init_FD_seed_frames(10000) | |
dk_raw, fd_raw = init_baselines('Main Slate') | |
dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id)) | |
fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id)) | |
sim_slate_var1 = st.radio("Which data are you loading?", ('Main Slate', 'Secondary Slate'), key='sim_slate_var1') | |
sim_site_var1 = st.radio("What site are you working with?", ('Draftkings', 'Fanduel'), key='sim_site_var1') | |
contest_var1 = st.selectbox("What contest size are you simulating?", ('Small', 'Medium', 'Large', 'Custom')) | |
if contest_var1 == 'Small': | |
Contest_Size = 1000 | |
elif contest_var1 == 'Medium': | |
Contest_Size = 5000 | |
elif contest_var1 == 'Large': | |
Contest_Size = 10000 | |
elif contest_var1 == 'Custom': | |
Contest_Size = st.number_input("Insert contest size", value=100, placeholder="Type a number under 10,000...") | |
strength_var1 = st.selectbox("How sharp is the field in the contest?", ('Very', 'Above Average', 'Average', 'Below Average', 'Not Very')) | |
if strength_var1 == 'Not Very': | |
sharp_split = 500000 | |
elif strength_var1 == 'Below Average': | |
sharp_split = 250000 | |
elif strength_var1 == 'Average': | |
sharp_split = 100000 | |
elif strength_var1 == 'Above Average': | |
sharp_split = 50000 | |
elif strength_var1 == 'Very': | |
sharp_split = 10000 | |
with col2: | |
if st.button("Run Contest Sim"): | |
if 'working_seed' in st.session_state: | |
st.session_state.maps_dict = { | |
'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)), | |
'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)), | |
'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)), | |
'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])), | |
'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)), | |
'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev)) | |
} | |
Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size) | |
Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners)) | |
# Initial setup | |
Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy']) | |
Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2 | |
Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str) | |
Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts())) | |
# Type Casting | |
type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32} | |
Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict) | |
# Sorting | |
st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100) | |
st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True) | |
# Data Copying | |
st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy() | |
# Data Copying | |
st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy() | |
else: | |
if sim_site_var1 == 'Draftkings': | |
if sim_slate_var1 == 'Main Slate': | |
st.session_state.working_seed = init_DK_seed_frames(sharp_split) | |
dk_raw, fd_raw = init_baselines('Main Slate') | |
dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id)) | |
elif sim_slate_var1 == 'Secondary Slate': | |
st.session_state.working_seed = init_DK_Secondary_seed_frames(sharp_split) | |
dk_raw, fd_raw = init_baselines('Secondary Slate') | |
dk_id_dict = dict(zip(dk_raw.Player, dk_raw.player_id)) | |
raw_baselines = dk_raw | |
column_names = dk_columns | |
elif sim_site_var1 == 'Fanduel': | |
if sim_slate_var1 == 'Main Slate': | |
st.session_state.working_seed = init_FD_seed_frames(sharp_split) | |
dk_raw, fd_raw = init_baselines('Main Slate') | |
fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id)) | |
elif sim_slate_var1 == 'Secondary Slate': | |
st.session_state.working_seed = init_FD_Secondary_seed_frames(sharp_split) | |
dk_raw, fd_raw = init_baselines('Secondary Slate') | |
fd_id_dict = dict(zip(fd_raw.Player, fd_raw.player_id)) | |
raw_baselines = fd_raw | |
column_names = fd_columns | |
st.session_state.maps_dict = { | |
'Projection_map':dict(zip(raw_baselines.Player,raw_baselines.Median)), | |
'Salary_map':dict(zip(raw_baselines.Player,raw_baselines.Salary)), | |
'Pos_map':dict(zip(raw_baselines.Player,raw_baselines.Position)), | |
'Own_map':dict(zip(raw_baselines.Player,raw_baselines['Own'])), | |
'Team_map':dict(zip(raw_baselines.Player,raw_baselines.Team)), | |
'STDev_map':dict(zip(raw_baselines.Player,raw_baselines.STDev)) | |
} | |
Sim_Winners = sim_contest(1000, st.session_state.working_seed, st.session_state.maps_dict, Contest_Size) | |
Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners)) | |
#st.table(Sim_Winner_Frame) | |
# Initial setup | |
Sim_Winner_Frame = pd.DataFrame(np.concatenate(Sim_Winners), columns=column_names + ['Fantasy']) | |
Sim_Winner_Frame['GPP_Proj'] = (Sim_Winner_Frame['proj'] + Sim_Winner_Frame['Fantasy']) / 2 | |
Sim_Winner_Frame['unique_id'] = Sim_Winner_Frame['proj'].astype(str) + Sim_Winner_Frame['salary'].astype(str) + Sim_Winner_Frame['Team'].astype(str) + Sim_Winner_Frame['Secondary'].astype(str) | |
Sim_Winner_Frame = Sim_Winner_Frame.assign(win_count=Sim_Winner_Frame['unique_id'].map(Sim_Winner_Frame['unique_id'].value_counts())) | |
# Type Casting | |
type_cast_dict = {'salary': int, 'proj': np.float16, 'Fantasy': np.float16, 'GPP_Proj': np.float32, 'Own': np.float32} | |
Sim_Winner_Frame = Sim_Winner_Frame.astype(type_cast_dict) | |
# Sorting | |
st.session_state.Sim_Winner_Frame = Sim_Winner_Frame.sort_values(by=['win_count', 'GPP_Proj'], ascending= [False, False]).copy().drop_duplicates(subset='unique_id').head(100) | |
st.session_state.Sim_Winner_Frame.drop(columns='unique_id', inplace=True) | |
# Data Copying | |
st.session_state.Sim_Winner_Export = Sim_Winner_Frame.copy() | |
for col in st.session_state.Sim_Winner_Export.iloc[:, 0:9].columns: | |
st.session_state.Sim_Winner_Export[col] = st.session_state.Sim_Winner_Export[col].map(dk_id_dict) | |
# Data Copying | |
st.session_state.Sim_Winner_Display = Sim_Winner_Frame.copy() | |
st.session_state.freq_copy = st.session_state.Sim_Winner_Display | |
if sim_site_var1 == 'Draftkings': | |
freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
elif sim_site_var1 == 'Fanduel': | |
freq_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:9].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
freq_working['Freq'] = freq_working['Freq'].astype(int) | |
freq_working['Position'] = freq_working['Player'].map(st.session_state.maps_dict['Pos_map']) | |
freq_working['Salary'] = freq_working['Player'].map(st.session_state.maps_dict['Salary_map']) | |
freq_working['Proj Own'] = freq_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100 | |
freq_working['Exposure'] = freq_working['Freq']/(1000) | |
freq_working['Edge'] = freq_working['Exposure'] - freq_working['Proj Own'] | |
freq_working['Team'] = freq_working['Player'].map(st.session_state.maps_dict['Team_map']) | |
st.session_state.player_freq = freq_working.copy() | |
if sim_site_var1 == 'Draftkings': | |
qb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:1].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
elif sim_site_var1 == 'Fanduel': | |
qb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,0:1].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
qb_working['Freq'] = qb_working['Freq'].astype(int) | |
qb_working['Position'] = qb_working['Player'].map(st.session_state.maps_dict['Pos_map']) | |
qb_working['Salary'] = qb_working['Player'].map(st.session_state.maps_dict['Salary_map']) | |
qb_working['Proj Own'] = qb_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100 | |
qb_working['Exposure'] = qb_working['Freq']/(1000) | |
qb_working['Edge'] = qb_working['Exposure'] - qb_working['Proj Own'] | |
qb_working['Team'] = qb_working['Player'].map(st.session_state.maps_dict['Team_map']) | |
st.session_state.qb_freq = qb_working.copy() | |
if sim_site_var1 == 'Draftkings': | |
rbwrte_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:7].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
elif sim_site_var1 == 'Fanduel': | |
rbwrte_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:7].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
rbwrte_working['Freq'] = rbwrte_working['Freq'].astype(int) | |
rbwrte_working['Position'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Pos_map']) | |
rbwrte_working['Salary'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Salary_map']) | |
rbwrte_working['Proj Own'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100 | |
rbwrte_working['Exposure'] = rbwrte_working['Freq']/(1000) | |
rbwrte_working['Edge'] = rbwrte_working['Exposure'] - rbwrte_working['Proj Own'] | |
rbwrte_working['Team'] = rbwrte_working['Player'].map(st.session_state.maps_dict['Team_map']) | |
st.session_state.rbwrte_freq = rbwrte_working.copy() | |
if sim_site_var1 == 'Draftkings': | |
rb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:3].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
elif sim_site_var1 == 'Fanduel': | |
rb_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,1:3].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
rb_working['Freq'] = rb_working['Freq'].astype(int) | |
rb_working['Position'] = rb_working['Player'].map(st.session_state.maps_dict['Pos_map']) | |
rb_working['Salary'] = rb_working['Player'].map(st.session_state.maps_dict['Salary_map']) | |
rb_working['Proj Own'] = rb_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100 | |
rb_working['Exposure'] = rb_working['Freq']/(1000) | |
rb_working['Edge'] = rb_working['Exposure'] - rb_working['Proj Own'] | |
rb_working['Team'] = rb_working['Player'].map(st.session_state.maps_dict['Team_map']) | |
st.session_state.rb_freq = rb_working.copy() | |
if sim_site_var1 == 'Draftkings': | |
wr_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,3:6].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
elif sim_site_var1 == 'Fanduel': | |
wr_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,3:6].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
wr_working['Freq'] = wr_working['Freq'].astype(int) | |
wr_working['Position'] = wr_working['Player'].map(st.session_state.maps_dict['Pos_map']) | |
wr_working['Salary'] = wr_working['Player'].map(st.session_state.maps_dict['Salary_map']) | |
wr_working['Proj Own'] = wr_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100 | |
wr_working['Exposure'] = wr_working['Freq']/(1000) | |
wr_working['Edge'] = wr_working['Exposure'] - wr_working['Proj Own'] | |
wr_working['Team'] = wr_working['Player'].map(st.session_state.maps_dict['Team_map']) | |
st.session_state.wr_freq = wr_working.copy() | |
if sim_site_var1 == 'Draftkings': | |
te_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,6:7].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
elif sim_site_var1 == 'Fanduel': | |
te_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,6:7].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
te_working['Freq'] = te_working['Freq'].astype(int) | |
te_working['Position'] = te_working['Player'].map(st.session_state.maps_dict['Pos_map']) | |
te_working['Salary'] = te_working['Player'].map(st.session_state.maps_dict['Salary_map']) | |
te_working['Proj Own'] = te_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100 | |
te_working['Exposure'] = te_working['Freq']/(1000) | |
te_working['Edge'] = te_working['Exposure'] - te_working['Proj Own'] | |
te_working['Team'] = te_working['Player'].map(st.session_state.maps_dict['Team_map']) | |
st.session_state.te_freq = te_working.copy() | |
if sim_site_var1 == 'Draftkings': | |
flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,7:8].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
elif sim_site_var1 == 'Fanduel': | |
flex_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,7:8].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
flex_working['Freq'] = flex_working['Freq'].astype(int) | |
flex_working['Position'] = flex_working['Player'].map(st.session_state.maps_dict['Pos_map']) | |
flex_working['Salary'] = flex_working['Player'].map(st.session_state.maps_dict['Salary_map']) | |
flex_working['Proj Own'] = flex_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100 | |
flex_working['Exposure'] = flex_working['Freq']/(1000) | |
flex_working['Edge'] = flex_working['Exposure'] - flex_working['Proj Own'] | |
flex_working['Team'] = flex_working['Player'].map(st.session_state.maps_dict['Team_map']) | |
st.session_state.flex_freq = flex_working.copy() | |
if sim_site_var1 == 'Draftkings': | |
dst_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
elif sim_site_var1 == 'Fanduel': | |
dst_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,8:9].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
dst_working['Freq'] = dst_working['Freq'].astype(int) | |
dst_working['Position'] = dst_working['Player'].map(st.session_state.maps_dict['Pos_map']) | |
dst_working['Salary'] = dst_working['Player'].map(st.session_state.maps_dict['Salary_map']) | |
dst_working['Proj Own'] = dst_working['Player'].map(st.session_state.maps_dict['Own_map']) / 100 | |
dst_working['Exposure'] = dst_working['Freq']/(1000) | |
dst_working['Edge'] = dst_working['Exposure'] - dst_working['Proj Own'] | |
dst_working['Team'] = dst_working['Player'].map(st.session_state.maps_dict['Team_map']) | |
st.session_state.dst_freq = dst_working.copy() | |
if sim_site_var1 == 'Draftkings': | |
team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
elif sim_site_var1 == 'Fanduel': | |
team_working = pd.DataFrame(np.column_stack(np.unique(st.session_state.freq_copy.iloc[:,11:12].values, return_counts=True)), | |
columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True) | |
team_working['Freq'] = team_working['Freq'].astype(int) | |
team_working['Exposure'] = team_working['Freq']/(1000) | |
st.session_state.team_freq = team_working.copy() | |
with st.container(): | |
if st.button("Reset Sim", key='reset_sim'): | |
for key in st.session_state.keys(): | |
del st.session_state[key] | |
if 'player_freq' in st.session_state: | |
player_split_var2 = st.radio("Are you wanting to isolate any lineups with specific players?", ('Full Players', 'Specific Players'), key='player_split_var2') | |
if player_split_var2 == 'Specific Players': | |
find_var2 = st.multiselect('Which players must be included in the lineups?', options = st.session_state.player_freq['Player'].unique()) | |
elif player_split_var2 == 'Full Players': | |
find_var2 = st.session_state.player_freq.Player.values.tolist() | |
if player_split_var2 == 'Specific Players': | |
st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame[np.equal.outer(st.session_state.Sim_Winner_Frame.to_numpy(), find_var2).any(axis=1).all(axis=1)] | |
if player_split_var2 == 'Full Players': | |
st.session_state.Sim_Winner_Display = st.session_state.Sim_Winner_Frame | |
if 'Sim_Winner_Display' in st.session_state: | |
st.dataframe(st.session_state.Sim_Winner_Display.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True) | |
if 'Sim_Winner_Export' in st.session_state: | |
st.download_button( | |
label="Export Full Frame", | |
data=st.session_state.Sim_Winner_Export.to_csv().encode('utf-8'), | |
file_name='MLB_consim_export.csv', | |
mime='text/csv', | |
) | |
tab1, tab2 = st.tabs(['Winning Frame Statistics', 'Flex Exposure Statistics']) | |
with tab1: | |
if 'Sim_Winner_Display' in st.session_state: | |
# Create a new dataframe with summary statistics | |
summary_df = pd.DataFrame({ | |
'Metric': ['Min', 'Average', 'Max', 'STDdev'], | |
'Salary': [ | |
st.session_state.Sim_Winner_Display['salary'].min(), | |
st.session_state.Sim_Winner_Display['salary'].mean(), | |
st.session_state.Sim_Winner_Display['salary'].max(), | |
st.session_state.Sim_Winner_Display['salary'].std() | |
], | |
'Proj': [ | |
st.session_state.Sim_Winner_Display['proj'].min(), | |
st.session_state.Sim_Winner_Display['proj'].mean(), | |
st.session_state.Sim_Winner_Display['proj'].max(), | |
st.session_state.Sim_Winner_Display['proj'].std() | |
], | |
'Own': [ | |
st.session_state.Sim_Winner_Display['Own'].min(), | |
st.session_state.Sim_Winner_Display['Own'].mean(), | |
st.session_state.Sim_Winner_Display['Own'].max(), | |
st.session_state.Sim_Winner_Display['Own'].std() | |
], | |
'Fantasy': [ | |
st.session_state.Sim_Winner_Display['Fantasy'].min(), | |
st.session_state.Sim_Winner_Display['Fantasy'].mean(), | |
st.session_state.Sim_Winner_Display['Fantasy'].max(), | |
st.session_state.Sim_Winner_Display['Fantasy'].std() | |
], | |
'GPP_Proj': [ | |
st.session_state.Sim_Winner_Display['GPP_Proj'].min(), | |
st.session_state.Sim_Winner_Display['GPP_Proj'].mean(), | |
st.session_state.Sim_Winner_Display['GPP_Proj'].max(), | |
st.session_state.Sim_Winner_Display['GPP_Proj'].std() | |
] | |
}) | |
# Set the index of the summary dataframe as the "Metric" column | |
summary_df = summary_df.set_index('Metric') | |
# Display the summary dataframe | |
st.subheader("Winning Frame Statistics") | |
st.dataframe(summary_df.style.format({ | |
'Salary': '{:.2f}', | |
'Proj': '{:.2f}', | |
'Fantasy': '{:.2f}', | |
'GPP_Proj': '{:.2f}' | |
}).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own', 'Fantasy', 'GPP_Proj']), use_container_width=True) | |
with tab2: | |
if 'Sim_Winner_Display' in st.session_state: | |
# Apply position mapping to FLEX column | |
flex_positions = st.session_state.freq_copy['FLEX'].map(st.session_state.maps_dict['Pos_map']) | |
# Count occurrences of each position in FLEX | |
flex_counts = flex_positions.value_counts() | |
# Calculate average statistics for each FLEX position | |
flex_stats = st.session_state.freq_copy.groupby(flex_positions).agg({ | |
'proj': 'mean', | |
'Own': 'mean', | |
'Fantasy': 'mean', | |
'GPP_Proj': 'mean' | |
}) | |
# Combine counts and average statistics | |
flex_summary = pd.concat([flex_counts, flex_stats], axis=1) | |
flex_summary.columns = ['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj'] | |
flex_summary = flex_summary.reset_index() | |
flex_summary.columns = ['Position', 'Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj'] | |
# Display the summary dataframe | |
st.subheader("FLEX Position Statistics") | |
st.dataframe(flex_summary.style.format({ | |
'Count': '{:.0f}', | |
'Avg Proj': '{:.2f}', | |
'Avg Fantasy': '{:.2f}', | |
'Avg GPP_Proj': '{:.2f}' | |
}).background_gradient(cmap='RdYlGn', axis=0, subset=['Count', 'Avg Proj', 'Avg Own', 'Avg Fantasy', 'Avg GPP_Proj']), use_container_width=True) | |
else: | |
st.write("Simulation data or position mapping not available.") | |
with st.container(): | |
tab1, tab2, tab3, tab4, tab5, tab6, tab7, tab8, tab9 = st.tabs(['Overall Exposures', 'QB Exposures', 'RB-WR-TE Exposures', 'RB Exposures', 'WR Exposures', 'TE Exposures', 'FLEX Exposures', 'DST Exposures', 'Team Exposures']) | |
with tab1: | |
if 'player_freq' in st.session_state: | |
st.dataframe(st.session_state.player_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True) | |
st.download_button( | |
label="Export Exposures", | |
data=st.session_state.player_freq.to_csv().encode('utf-8'), | |
file_name='player_freq_export.csv', | |
mime='text/csv', | |
key='overall' | |
) | |
with tab2: | |
if 'qb_freq' in st.session_state: | |
st.dataframe(st.session_state.qb_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True) | |
st.download_button( | |
label="Export Exposures", | |
data=st.session_state.qb_freq.to_csv().encode('utf-8'), | |
file_name='qb_freq.csv', | |
mime='text/csv', | |
key='qb' | |
) | |
with tab3: | |
if 'rbwrte_freq' in st.session_state: | |
st.dataframe(st.session_state.rbwrte_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True) | |
st.download_button( | |
label="Export Exposures", | |
data=st.session_state.rbwrte_freq.to_csv().encode('utf-8'), | |
file_name='rbwrte_freq.csv', | |
mime='text/csv', | |
key='rbwrte' | |
) | |
with tab4: | |
if 'rb_freq' in st.session_state: | |
st.dataframe(st.session_state.rb_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True) | |
st.download_button( | |
label="Export Exposures", | |
data=st.session_state.rb_freq.to_csv().encode('utf-8'), | |
file_name='rb_freq.csv', | |
mime='text/csv', | |
key='rb' | |
) | |
with tab5: | |
if 'wr_freq' in st.session_state: | |
st.dataframe(st.session_state.wr_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True) | |
st.download_button( | |
label="Export Exposures", | |
data=st.session_state.wr_freq.to_csv().encode('utf-8'), | |
file_name='wr_freq.csv', | |
mime='text/csv', | |
key='wr' | |
) | |
with tab6: | |
if 'te_freq' in st.session_state: | |
st.dataframe(st.session_state.te_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True) | |
st.download_button( | |
label="Export Exposures", | |
data=st.session_state.te_freq.to_csv().encode('utf-8'), | |
file_name='te_freq.csv', | |
mime='text/csv', | |
key='te' | |
) | |
with tab7: | |
if 'flex_freq' in st.session_state: | |
st.dataframe(st.session_state.flex_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True) | |
st.download_button( | |
label="Export Exposures", | |
data=st.session_state.flex_freq.to_csv().encode('utf-8'), | |
file_name='flex_freq.csv', | |
mime='text/csv', | |
key='flex' | |
) | |
with tab8: | |
if 'dst_freq' in st.session_state: | |
st.dataframe(st.session_state.dst_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(freq_format, precision=2), use_container_width = True) | |
st.download_button( | |
label="Export Exposures", | |
data=st.session_state.dst_freq.to_csv().encode('utf-8'), | |
file_name='dst_freq.csv', | |
mime='text/csv', | |
key='dst' | |
) | |
with tab9: | |
if 'team_freq' in st.session_state: | |
st.dataframe(st.session_state.team_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(percentages_format, precision=2), use_container_width = True) | |
st.download_button( | |
label="Export Exposures", | |
data=st.session_state.team_freq.to_csv().encode('utf-8'), | |
file_name='team_freq.csv', | |
mime='text/csv', | |
key='team' | |
) |