Spaces:
Running
Running
James McCool
commited on
Commit
·
7764903
1
Parent(s):
5df1223
Refactor UI layout and add custom tab styling
Browse files- Implement custom CSS for Streamlit tabs with improved visual design
- Reorganize tab1 and tab2 layouts using expanders and containers
- Enhance user interface with more structured and responsive elements
- Improve data display and interaction in both tabs
app.py
CHANGED
@@ -29,6 +29,37 @@ player_roo_format = {'Top_finish': '{:.2%}','Top_5_finish': '{:.2%}', 'Top_10_fi
|
|
29 |
dk_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own']
|
30 |
fd_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own']
|
31 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
32 |
@st.cache_resource(ttl = 60)
|
33 |
def init_baselines():
|
34 |
collection = db["PGA_Range_of_Outcomes"]
|
@@ -120,30 +151,31 @@ salaryCut = 0
|
|
120 |
tab1, tab2 = st.tabs(["Player Overall Projections", "Optimals and Exposures"])
|
121 |
|
122 |
with tab1:
|
123 |
-
|
124 |
-
|
125 |
-
|
126 |
-
|
127 |
-
|
128 |
-
|
129 |
-
|
130 |
-
|
131 |
-
|
132 |
-
|
|
|
133 |
|
134 |
-
|
135 |
-
|
136 |
-
|
137 |
-
|
138 |
|
139 |
-
|
140 |
-
|
141 |
-
|
142 |
-
|
143 |
-
|
144 |
-
|
145 |
-
|
146 |
-
|
147 |
with hold_container:
|
148 |
if type_var == "Full Slate":
|
149 |
display = hold_display[hold_display['Site'] == site_var]
|
@@ -173,8 +205,7 @@ with tab1:
|
|
173 |
)
|
174 |
|
175 |
with tab2:
|
176 |
-
|
177 |
-
with col1:
|
178 |
if st.button("Load/Reset Data", key='reset2'):
|
179 |
st.cache_data.clear()
|
180 |
roo_data, sd_roo_data, timestamp = init_baselines()
|
@@ -253,196 +284,195 @@ with tab2:
|
|
253 |
file_name='NBA_optimals_export.csv',
|
254 |
mime='text/csv',
|
255 |
)
|
256 |
-
with col2:
|
257 |
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
st.session_state.working_seed = dk_lineups.copy()
|
265 |
-
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
266 |
-
elif 'working_seed' not in st.session_state:
|
267 |
st.session_state.working_seed = dk_lineups.copy()
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
st.session_state.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
274 |
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
|
281 |
-
|
282 |
-
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
283 |
-
elif 'working_seed' not in st.session_state:
|
284 |
st.session_state.working_seed = fd_lineups.copy()
|
285 |
-
|
286 |
-
|
287 |
-
|
288 |
-
|
289 |
-
|
290 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
291 |
|
292 |
-
|
293 |
-
|
294 |
-
|
295 |
-
|
296 |
-
|
297 |
-
|
298 |
-
|
299 |
-
|
300 |
-
|
301 |
-
|
302 |
-
|
303 |
-
|
|
|
|
|
|
|
304 |
if site_var1 == 'Draftkings':
|
305 |
-
st.session_state.
|
306 |
elif site_var1 == 'Fanduel':
|
307 |
-
st.session_state.
|
308 |
-
|
309 |
-
|
310 |
-
|
311 |
-
|
312 |
-
|
313 |
-
|
314 |
-
|
315 |
-
|
316 |
-
|
317 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
318 |
if 'working_seed' in st.session_state:
|
319 |
-
# Create a new dataframe with summary statistics
|
320 |
if site_var1 == 'Draftkings':
|
321 |
-
|
322 |
-
'Metric': ['Min', 'Average', 'Max', 'STDdev'],
|
323 |
-
'Salary': [
|
324 |
-
np.min(st.session_state.working_seed[:,6]),
|
325 |
-
np.mean(st.session_state.working_seed[:,6]),
|
326 |
-
np.max(st.session_state.working_seed[:,6]),
|
327 |
-
np.std(st.session_state.working_seed[:,6])
|
328 |
-
],
|
329 |
-
'Proj': [
|
330 |
-
np.min(st.session_state.working_seed[:,7]),
|
331 |
-
np.mean(st.session_state.working_seed[:,7]),
|
332 |
-
np.max(st.session_state.working_seed[:,7]),
|
333 |
-
np.std(st.session_state.working_seed[:,7])
|
334 |
-
],
|
335 |
-
'Own': [
|
336 |
-
np.min(st.session_state.working_seed[:,8]),
|
337 |
-
np.mean(st.session_state.working_seed[:,8]),
|
338 |
-
np.max(st.session_state.working_seed[:,8]),
|
339 |
-
np.std(st.session_state.working_seed[:,8])
|
340 |
-
]
|
341 |
-
})
|
342 |
elif site_var1 == 'Fanduel':
|
343 |
-
|
344 |
-
'Metric': ['Min', 'Average', 'Max', 'STDdev'],
|
345 |
-
'Salary': [
|
346 |
-
np.min(st.session_state.working_seed[:,6]),
|
347 |
-
np.mean(st.session_state.working_seed[:,6]),
|
348 |
-
np.max(st.session_state.working_seed[:,6]),
|
349 |
-
np.std(st.session_state.working_seed[:,6])
|
350 |
-
],
|
351 |
-
'Proj': [
|
352 |
-
np.min(st.session_state.working_seed[:,7]),
|
353 |
-
np.mean(st.session_state.working_seed[:,7]),
|
354 |
-
np.max(st.session_state.working_seed[:,7]),
|
355 |
-
np.std(st.session_state.working_seed[:,7])
|
356 |
-
],
|
357 |
-
'Own': [
|
358 |
-
np.min(st.session_state.working_seed[:,8]),
|
359 |
-
np.mean(st.session_state.working_seed[:,8]),
|
360 |
-
np.max(st.session_state.working_seed[:,8]),
|
361 |
-
np.std(st.session_state.working_seed[:,8])
|
362 |
-
]
|
363 |
-
})
|
364 |
-
|
365 |
-
# Set the index of the summary dataframe as the "Metric" column
|
366 |
-
summary_df = summary_df.set_index('Metric')
|
367 |
-
|
368 |
-
# Display the summary dataframe
|
369 |
-
st.subheader("Optimal Statistics")
|
370 |
-
st.dataframe(summary_df.style.format({
|
371 |
-
'Salary': '{:.2f}',
|
372 |
-
'Proj': '{:.2f}',
|
373 |
-
'Own': '{:.2f}'
|
374 |
-
}).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own']), use_container_width=True)
|
375 |
-
|
376 |
-
with st.container():
|
377 |
-
tab1, tab2 = st.tabs(["Display Frequency", "Seed Frame Frequency"])
|
378 |
-
with tab1:
|
379 |
-
if 'data_export_display' in st.session_state:
|
380 |
-
if site_var1 == 'Draftkings':
|
381 |
-
player_columns = st.session_state.data_export_display.iloc[:, :6]
|
382 |
-
elif site_var1 == 'Fanduel':
|
383 |
-
player_columns = st.session_state.data_export_display.iloc[:, :6]
|
384 |
-
|
385 |
-
# Flatten the DataFrame and count unique values
|
386 |
-
value_counts = player_columns.values.flatten().tolist()
|
387 |
-
value_counts = pd.Series(value_counts).value_counts()
|
388 |
-
|
389 |
-
percentages = (value_counts / lineup_num_var * 100).round(2)
|
390 |
-
|
391 |
-
# Create a DataFrame with the results
|
392 |
-
summary_df = pd.DataFrame({
|
393 |
-
'Player': value_counts.index,
|
394 |
-
'Frequency': value_counts.values,
|
395 |
-
'Percentage': percentages.values
|
396 |
-
})
|
397 |
-
|
398 |
-
# Sort by frequency in descending order
|
399 |
-
summary_df['Salary'] = summary_df['Player'].map(player_salaries)
|
400 |
-
summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
|
401 |
-
summary_df = summary_df.sort_values('Frequency', ascending=False)
|
402 |
-
summary_df = summary_df.set_index('Player')
|
403 |
-
|
404 |
-
# Display the table
|
405 |
-
st.write("Player Frequency Table:")
|
406 |
-
st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True)
|
407 |
|
408 |
-
|
409 |
-
|
410 |
-
|
411 |
-
|
412 |
-
|
413 |
-
|
414 |
-
|
415 |
-
|
416 |
-
|
417 |
-
|
418 |
-
|
419 |
-
player_columns = st.session_state.working_seed[:, :6]
|
420 |
-
|
421 |
-
# Flatten the DataFrame and count unique values
|
422 |
-
value_counts = player_columns.flatten().tolist()
|
423 |
-
value_counts = pd.Series(value_counts).value_counts()
|
424 |
-
|
425 |
-
percentages = (value_counts / len(st.session_state.working_seed) * 100).round(2)
|
426 |
-
# Create a DataFrame with the results
|
427 |
-
summary_df = pd.DataFrame({
|
428 |
-
'Player': value_counts.index,
|
429 |
-
'Frequency': value_counts.values,
|
430 |
-
'Percentage': percentages.values
|
431 |
-
})
|
432 |
-
|
433 |
-
# Sort by frequency in descending order
|
434 |
-
summary_df['Salary'] = summary_df['Player'].map(player_salaries)
|
435 |
-
summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
|
436 |
-
summary_df = summary_df.sort_values('Frequency', ascending=False)
|
437 |
-
summary_df = summary_df.set_index('Player')
|
438 |
-
|
439 |
-
# Display the table
|
440 |
-
st.write("Seed Frame Frequency Table:")
|
441 |
-
st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True)
|
442 |
|
443 |
-
|
444 |
-
|
445 |
-
|
446 |
-
|
447 |
-
|
448 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
dk_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own']
|
30 |
fd_columns = ['FLEX1', 'FLEX2', 'FLEX3', 'FLEX4', 'FLEX5', 'FLEX6', 'salary', 'proj', 'Own']
|
31 |
|
32 |
+
st.markdown("""
|
33 |
+
<style>
|
34 |
+
/* Tab styling */
|
35 |
+
.stTabs [data-baseweb="tab-list"] {
|
36 |
+
gap: 8px;
|
37 |
+
padding: 4px;
|
38 |
+
}
|
39 |
+
|
40 |
+
.stTabs [data-baseweb="tab"] {
|
41 |
+
height: 50px;
|
42 |
+
white-space: pre-wrap;
|
43 |
+
background-color: #FFD700;
|
44 |
+
color: white;
|
45 |
+
border-radius: 10px;
|
46 |
+
gap: 1px;
|
47 |
+
padding: 10px 20px;
|
48 |
+
font-weight: bold;
|
49 |
+
transition: all 0.3s ease;
|
50 |
+
}
|
51 |
+
|
52 |
+
.stTabs [aria-selected="true"] {
|
53 |
+
background-color: #DAA520;
|
54 |
+
color: white;
|
55 |
+
}
|
56 |
+
|
57 |
+
.stTabs [data-baseweb="tab"]:hover {
|
58 |
+
background-color: #DAA520;
|
59 |
+
cursor: pointer;
|
60 |
+
}
|
61 |
+
</style>""", unsafe_allow_html=True)
|
62 |
+
|
63 |
@st.cache_resource(ttl = 60)
|
64 |
def init_baselines():
|
65 |
collection = db["PGA_Range_of_Outcomes"]
|
|
|
151 |
tab1, tab2 = st.tabs(["Player Overall Projections", "Optimals and Exposures"])
|
152 |
|
153 |
with tab1:
|
154 |
+
with st.expander("Info and Filters"):
|
155 |
+
if st.button("Reset Data", key='reset1'):
|
156 |
+
# Clear values from *all* all in-memory and on-disk data caches:
|
157 |
+
# i.e. clear values from both square and cube
|
158 |
+
st.cache_data.clear()
|
159 |
+
roo_data, sd_roo_data, timestamp = init_baselines()
|
160 |
+
dk_lineups = init_DK_lineups('Regular')
|
161 |
+
fd_lineups = init_FD_lineups('Regular')
|
162 |
+
hold_display = roo_data
|
163 |
+
for key in st.session_state.keys():
|
164 |
+
del st.session_state[key]
|
165 |
|
166 |
+
st.write(timestamp)
|
167 |
+
info_container = st.empty()
|
168 |
+
options_container = st.empty()
|
169 |
+
hold_container = st.empty()
|
170 |
|
171 |
+
with options_container:
|
172 |
+
col1, col2, col3 = st.columns(3)
|
173 |
+
with col1:
|
174 |
+
view_var = st.radio("Select a View", ["Simple", "Advanced"])
|
175 |
+
with col2:
|
176 |
+
site_var = st.radio("Select a Site", ["Draftkings", "FanDuel"])
|
177 |
+
with col3:
|
178 |
+
type_var = st.radio("Select a Type", ["Full Slate", "Showdown"])
|
179 |
with hold_container:
|
180 |
if type_var == "Full Slate":
|
181 |
display = hold_display[hold_display['Site'] == site_var]
|
|
|
205 |
)
|
206 |
|
207 |
with tab2:
|
208 |
+
with st.expander("Info and Filters"):
|
|
|
209 |
if st.button("Load/Reset Data", key='reset2'):
|
210 |
st.cache_data.clear()
|
211 |
roo_data, sd_roo_data, timestamp = init_baselines()
|
|
|
284 |
file_name='NBA_optimals_export.csv',
|
285 |
mime='text/csv',
|
286 |
)
|
|
|
287 |
|
288 |
+
if site_var1 == 'Draftkings':
|
289 |
+
if 'working_seed' in st.session_state:
|
290 |
+
st.session_state.working_seed = st.session_state.working_seed
|
291 |
+
if player_var1 == 'Specific Players':
|
292 |
+
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)]
|
293 |
+
elif player_var1 == 'Full Slate':
|
|
|
|
|
|
|
294 |
st.session_state.working_seed = dk_lineups.copy()
|
295 |
+
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
296 |
+
elif 'working_seed' not in st.session_state:
|
297 |
+
st.session_state.working_seed = dk_lineups.copy()
|
298 |
+
st.session_state.working_seed = st.session_state.working_seed
|
299 |
+
if player_var1 == 'Specific Players':
|
300 |
+
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)]
|
301 |
+
elif player_var1 == 'Full Slate':
|
302 |
+
st.session_state.working_seed = dk_lineups.copy()
|
303 |
+
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
304 |
+
|
305 |
+
elif site_var1 == 'Fanduel':
|
306 |
+
if 'working_seed' in st.session_state:
|
307 |
+
st.session_state.working_seed = st.session_state.working_seed
|
308 |
+
if player_var1 == 'Specific Players':
|
309 |
+
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)]
|
310 |
+
elif player_var1 == 'Full Slate':
|
311 |
+
st.session_state.working_seed = fd_lineups.copy()
|
312 |
+
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
313 |
+
elif 'working_seed' not in st.session_state:
|
314 |
+
st.session_state.working_seed = fd_lineups.copy()
|
315 |
+
st.session_state.working_seed = st.session_state.working_seed
|
316 |
+
if player_var1 == 'Specific Players':
|
317 |
+
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)]
|
318 |
+
elif player_var1 == 'Full Slate':
|
319 |
+
st.session_state.working_seed = fd_lineups.copy()
|
320 |
+
st.session_state.data_export_display = pd.DataFrame(st.session_state.working_seed[0:lineup_num_var], columns=column_names)
|
321 |
+
|
322 |
+
export_file = st.session_state.data_export_display.copy()
|
323 |
+
# if site_var1 == 'Draftkings':
|
324 |
+
# for col_idx in range(6):
|
325 |
+
# export_file.iloc[:, col_idx] = export_file.iloc[:, col_idx].map(id_dict)
|
326 |
+
# elif site_var1 == 'Fanduel':
|
327 |
+
# for col_idx in range(6):
|
328 |
+
# export_file.iloc[:, col_idx] = export_file.iloc[:, col_idx].map(id_dict)
|
329 |
|
330 |
+
with st.container():
|
331 |
+
if st.button("Reset Optimals", key='reset3'):
|
332 |
+
for key in st.session_state.keys():
|
333 |
+
del st.session_state[key]
|
334 |
+
if site_var1 == 'Draftkings':
|
335 |
+
st.session_state.working_seed = dk_lineups.copy()
|
336 |
+
elif site_var1 == 'Fanduel':
|
|
|
|
|
337 |
st.session_state.working_seed = fd_lineups.copy()
|
338 |
+
if 'data_export_display' in st.session_state:
|
339 |
+
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)
|
340 |
+
st.download_button(
|
341 |
+
label="Export display optimals",
|
342 |
+
data=convert_df(export_file),
|
343 |
+
file_name='NBA_display_optimals.csv',
|
344 |
+
mime='text/csv',
|
345 |
+
)
|
346 |
+
|
347 |
+
with st.container():
|
348 |
+
if 'working_seed' in st.session_state:
|
349 |
+
# Create a new dataframe with summary statistics
|
350 |
+
if site_var1 == 'Draftkings':
|
351 |
+
summary_df = pd.DataFrame({
|
352 |
+
'Metric': ['Min', 'Average', 'Max', 'STDdev'],
|
353 |
+
'Salary': [
|
354 |
+
np.min(st.session_state.working_seed[:,6]),
|
355 |
+
np.mean(st.session_state.working_seed[:,6]),
|
356 |
+
np.max(st.session_state.working_seed[:,6]),
|
357 |
+
np.std(st.session_state.working_seed[:,6])
|
358 |
+
],
|
359 |
+
'Proj': [
|
360 |
+
np.min(st.session_state.working_seed[:,7]),
|
361 |
+
np.mean(st.session_state.working_seed[:,7]),
|
362 |
+
np.max(st.session_state.working_seed[:,7]),
|
363 |
+
np.std(st.session_state.working_seed[:,7])
|
364 |
+
],
|
365 |
+
'Own': [
|
366 |
+
np.min(st.session_state.working_seed[:,8]),
|
367 |
+
np.mean(st.session_state.working_seed[:,8]),
|
368 |
+
np.max(st.session_state.working_seed[:,8]),
|
369 |
+
np.std(st.session_state.working_seed[:,8])
|
370 |
+
]
|
371 |
+
})
|
372 |
+
elif site_var1 == 'Fanduel':
|
373 |
+
summary_df = pd.DataFrame({
|
374 |
+
'Metric': ['Min', 'Average', 'Max', 'STDdev'],
|
375 |
+
'Salary': [
|
376 |
+
np.min(st.session_state.working_seed[:,6]),
|
377 |
+
np.mean(st.session_state.working_seed[:,6]),
|
378 |
+
np.max(st.session_state.working_seed[:,6]),
|
379 |
+
np.std(st.session_state.working_seed[:,6])
|
380 |
+
],
|
381 |
+
'Proj': [
|
382 |
+
np.min(st.session_state.working_seed[:,7]),
|
383 |
+
np.mean(st.session_state.working_seed[:,7]),
|
384 |
+
np.max(st.session_state.working_seed[:,7]),
|
385 |
+
np.std(st.session_state.working_seed[:,7])
|
386 |
+
],
|
387 |
+
'Own': [
|
388 |
+
np.min(st.session_state.working_seed[:,8]),
|
389 |
+
np.mean(st.session_state.working_seed[:,8]),
|
390 |
+
np.max(st.session_state.working_seed[:,8]),
|
391 |
+
np.std(st.session_state.working_seed[:,8])
|
392 |
+
]
|
393 |
+
})
|
394 |
|
395 |
+
# Set the index of the summary dataframe as the "Metric" column
|
396 |
+
summary_df = summary_df.set_index('Metric')
|
397 |
+
|
398 |
+
# Display the summary dataframe
|
399 |
+
st.subheader("Optimal Statistics")
|
400 |
+
st.dataframe(summary_df.style.format({
|
401 |
+
'Salary': '{:.2f}',
|
402 |
+
'Proj': '{:.2f}',
|
403 |
+
'Own': '{:.2f}'
|
404 |
+
}).background_gradient(cmap='RdYlGn', axis=0, subset=['Salary', 'Proj', 'Own']), use_container_width=True)
|
405 |
+
|
406 |
+
with st.container():
|
407 |
+
tab1, tab2 = st.tabs(["Display Frequency", "Seed Frame Frequency"])
|
408 |
+
with tab1:
|
409 |
+
if 'data_export_display' in st.session_state:
|
410 |
if site_var1 == 'Draftkings':
|
411 |
+
player_columns = st.session_state.data_export_display.iloc[:, :6]
|
412 |
elif site_var1 == 'Fanduel':
|
413 |
+
player_columns = st.session_state.data_export_display.iloc[:, :6]
|
414 |
+
|
415 |
+
# Flatten the DataFrame and count unique values
|
416 |
+
value_counts = player_columns.values.flatten().tolist()
|
417 |
+
value_counts = pd.Series(value_counts).value_counts()
|
418 |
+
|
419 |
+
percentages = (value_counts / lineup_num_var * 100).round(2)
|
420 |
+
|
421 |
+
# Create a DataFrame with the results
|
422 |
+
summary_df = pd.DataFrame({
|
423 |
+
'Player': value_counts.index,
|
424 |
+
'Frequency': value_counts.values,
|
425 |
+
'Percentage': percentages.values
|
426 |
+
})
|
427 |
+
|
428 |
+
# Sort by frequency in descending order
|
429 |
+
summary_df['Salary'] = summary_df['Player'].map(player_salaries)
|
430 |
+
summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
|
431 |
+
summary_df = summary_df.sort_values('Frequency', ascending=False)
|
432 |
+
summary_df = summary_df.set_index('Player')
|
433 |
+
|
434 |
+
# Display the table
|
435 |
+
st.write("Player Frequency Table:")
|
436 |
+
st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True)
|
437 |
+
|
438 |
+
st.download_button(
|
439 |
+
label="Export player frequency",
|
440 |
+
data=convert_df_to_csv(summary_df),
|
441 |
+
file_name='PGA_player_frequency.csv',
|
442 |
+
mime='text/csv',
|
443 |
+
)
|
444 |
+
with tab2:
|
445 |
if 'working_seed' in st.session_state:
|
|
|
446 |
if site_var1 == 'Draftkings':
|
447 |
+
player_columns = st.session_state.working_seed[:, :6]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
448 |
elif site_var1 == 'Fanduel':
|
449 |
+
player_columns = st.session_state.working_seed[:, :6]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
450 |
|
451 |
+
# Flatten the DataFrame and count unique values
|
452 |
+
value_counts = player_columns.flatten().tolist()
|
453 |
+
value_counts = pd.Series(value_counts).value_counts()
|
454 |
+
|
455 |
+
percentages = (value_counts / len(st.session_state.working_seed) * 100).round(2)
|
456 |
+
# Create a DataFrame with the results
|
457 |
+
summary_df = pd.DataFrame({
|
458 |
+
'Player': value_counts.index,
|
459 |
+
'Frequency': value_counts.values,
|
460 |
+
'Percentage': percentages.values
|
461 |
+
})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
462 |
|
463 |
+
# Sort by frequency in descending order
|
464 |
+
summary_df['Salary'] = summary_df['Player'].map(player_salaries)
|
465 |
+
summary_df = summary_df[['Player', 'Salary', 'Frequency', 'Percentage']]
|
466 |
+
summary_df = summary_df.sort_values('Frequency', ascending=False)
|
467 |
+
summary_df = summary_df.set_index('Player')
|
468 |
+
|
469 |
+
# Display the table
|
470 |
+
st.write("Seed Frame Frequency Table:")
|
471 |
+
st.dataframe(summary_df.style.format({'Percentage': '{:.2f}%'}), height=500, use_container_width=True)
|
472 |
+
|
473 |
+
st.download_button(
|
474 |
+
label="Export seed frame frequency",
|
475 |
+
data=convert_df_to_csv(summary_df),
|
476 |
+
file_name='PGA_seed_frame_frequency.csv',
|
477 |
+
mime='text/csv',
|
478 |
+
)
|