Multichem commited on
Commit
7dc696f
·
1 Parent(s): 1d20cec

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +339 -0
app.py ADDED
@@ -0,0 +1,339 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ st.set_page_config(layout="wide")
3
+
4
+ for name in dir():
5
+ if not name.startswith('_'):
6
+ del globals()[name]
7
+
8
+ import numpy as np
9
+ import pandas as pd
10
+ import streamlit as st
11
+ import gspread
12
+ import random
13
+ import gc
14
+
15
+ tab1, tab2 = st.tabs(['Uploads', 'Manage Portfolio'])
16
+
17
+ with tab1:
18
+ with st.container():
19
+ col1, col2 = st.columns([3, 3])
20
+
21
+ with col1:
22
+ st.info("The Projections file can have any columns in any order, but must contain columns explicitly named: 'Player', 'Salary', 'Position', 'Team', 'Opp', 'Median', and 'Own'. Upload your projections first to avoid an error message.")
23
+ proj_file = st.file_uploader("Upload Projections File", key = 'proj_uploader')
24
+
25
+ if proj_file is not None:
26
+ try:
27
+ proj_dataframe = pd.read_csv(proj_file)
28
+ proj_dataframe = proj_dataframe.dropna(subset='Median')
29
+ proj_dataframe['Player'] = proj_dataframe['Player'].str.strip()
30
+ try:
31
+ proj_dataframe['Own'] = proj_dataframe['Own'].str.strip('%').astype(float)
32
+ except:
33
+ pass
34
+
35
+ except:
36
+ proj_dataframe = pd.read_excel(proj_file)
37
+ proj_dataframe = proj_dataframe.dropna(subset='Median')
38
+ proj_dataframe['Player'] = proj_dataframe['Player'].str.strip()
39
+ try:
40
+ proj_dataframe['Own'] = proj_dataframe['Own'].str.strip('%').astype(float)
41
+ except:
42
+ pass
43
+ st.table(proj_dataframe.head(10))
44
+ player_salary_dict = dict(zip(proj_dataframe.Player, proj_dataframe.Salary))
45
+ player_proj_dict = dict(zip(proj_dataframe.Player, proj_dataframe.Median))
46
+ player_own_dict = dict(zip(proj_dataframe.Player, proj_dataframe.Own))
47
+
48
+ with col2:
49
+ st.info("The Portfolio file must contain only columns in order and explicitly named: 'PG', 'SG', 'SF', 'PF', 'C', 'G', 'F', and 'UTIL'. Upload your projections first to avoid an error message.")
50
+ portfolio_file = st.file_uploader("Upload Portfolio File", key = 'portfolio_uploader')
51
+
52
+ if portfolio_file is not None:
53
+ try:
54
+ portfolio_dataframe = pd.read_csv(portfolio_file)
55
+
56
+ except:
57
+ portfolio_dataframe = pd.read_excel(portfolio_file)
58
+
59
+ try:
60
+ try:
61
+ portfolio_dataframe.columns=['PG', 'SG', 'SF', 'PF', 'C', 'G', 'F', 'UTIL']
62
+ split_portfolio = portfolio_dataframe
63
+ split_portfolio[['PG', 'PG_ID']] = split_portfolio.PG.str.split("(", n=1, expand = True)
64
+ split_portfolio[['SG', 'SG_ID']] = split_portfolio.SG.str.split("(", n=1, expand = True)
65
+ split_portfolio[['SF', 'SF_ID']] = split_portfolio.SF.str.split("(", n=1, expand = True)
66
+ split_portfolio[['PF', 'PF_ID']] = split_portfolio.PF.str.split("(", n=1, expand = True)
67
+ split_portfolio[['C', 'C_ID']] = split_portfolio.C.str.split("(", n=1, expand = True)
68
+ split_portfolio[['G', 'G_ID']] = split_portfolio.G.str.split("(", n=1, expand = True)
69
+ split_portfolio[['F', 'F_ID']] = split_portfolio.F.str.split("(", n=1, expand = True)
70
+ split_portfolio[['UTIL', 'UTIL_ID']] = split_portfolio.UTIL.str.split("(", n=1, expand = True)
71
+
72
+ split_portfolio['PG'] = split_portfolio['PG'].str.strip()
73
+ split_portfolio['SG'] = split_portfolio['SG'].str.strip()
74
+ split_portfolio['SF'] = split_portfolio['SF'].str.strip()
75
+ split_portfolio['PF'] = split_portfolio['PF'].str.strip()
76
+ split_portfolio['C'] = split_portfolio['C'].str.strip()
77
+ split_portfolio['G'] = split_portfolio['G'].str.strip()
78
+ split_portfolio['F'] = split_portfolio['F'].str.strip()
79
+ split_portfolio['UTIL'] = split_portfolio['UTIL'].str.strip()
80
+
81
+ split_portfolio['Salary'] = sum([split_portfolio['PG'].map(player_salary_dict),
82
+ split_portfolio['SG'].map(player_salary_dict),
83
+ split_portfolio['SF'].map(player_salary_dict),
84
+ split_portfolio['PF'].map(player_salary_dict),
85
+ split_portfolio['C'].map(player_salary_dict),
86
+ split_portfolio['G'].map(player_salary_dict),
87
+ split_portfolio['F'].map(player_salary_dict),
88
+ split_portfolio['UTIL'].map(player_salary_dict)])
89
+
90
+ split_portfolio['Projection'] = sum([split_portfolio['PG'].map(player_proj_dict),
91
+ split_portfolio['SG'].map(player_proj_dict),
92
+ split_portfolio['SF'].map(player_proj_dict),
93
+ split_portfolio['PF'].map(player_proj_dict),
94
+ split_portfolio['C'].map(player_proj_dict),
95
+ split_portfolio['G'].map(player_proj_dict),
96
+ split_portfolio['F'].map(player_proj_dict),
97
+ split_portfolio['UTIL'].map(player_proj_dict)])
98
+
99
+ split_portfolio['Ownership'] = sum([split_portfolio['PG'].map(player_own_dict),
100
+ split_portfolio['SG'].map(player_own_dict),
101
+ split_portfolio['SF'].map(player_own_dict),
102
+ split_portfolio['PF'].map(player_own_dict),
103
+ split_portfolio['C'].map(player_own_dict),
104
+ split_portfolio['G'].map(player_own_dict),
105
+ split_portfolio['F'].map(player_own_dict),
106
+ split_portfolio['UTIL'].map(player_own_dict)])
107
+
108
+ st.table(split_portfolio.head(10))
109
+
110
+
111
+ except:
112
+ portfolio_dataframe.columns=['PG', 'SG', 'SF', 'PF', 'C', 'G', 'F', 'UTIL']
113
+
114
+ split_portfolio = portfolio_dataframe
115
+ split_portfolio[['PG_ID', 'PG']] = split_portfolio.PG.str.split(":", n=1, expand = True)
116
+ split_portfolio[['SG_ID', 'SG']] = split_portfolio.SG.str.split(":", n=1, expand = True)
117
+ split_portfolio[['SF_ID', 'SF']] = split_portfolio.SF.str.split(":", n=1, expand = True)
118
+ split_portfolio[['PF_ID', 'PF']] = split_portfolio.PF.str.split(":", n=1, expand = True)
119
+ split_portfolio[['C_ID', 'C']] = split_portfolio.C.str.split(":", n=1, expand = True)
120
+ split_portfolio[['G_ID', 'G']] = split_portfolio.G.str.split(":", n=1, expand = True)
121
+ split_portfolio[['F_ID', 'F']] = split_portfolio.F.str.split(":", n=1, expand = True)
122
+ split_portfolio[['UTIL_ID', 'UTIL']] = split_portfolio.UTIL.str.split(":", n=1, expand = True)
123
+
124
+ split_portfolio['PG'] = split_portfolio['PG'].str.strip()
125
+ split_portfolio['SG'] = split_portfolio['SG'].str.strip()
126
+ split_portfolio['SF'] = split_portfolio['SF'].str.strip()
127
+ split_portfolio['PF'] = split_portfolio['PF'].str.strip()
128
+ split_portfolio['C'] = split_portfolio['C'].str.strip()
129
+ split_portfolio['G'] = split_portfolio['G'].str.strip()
130
+ split_portfolio['F'] = split_portfolio['F'].str.strip()
131
+ split_portfolio['UTIL'] = split_portfolio['UTIL'].str.strip()
132
+
133
+ split_portfolio['Salary'] = sum([split_portfolio['PG'].map(player_salary_dict),
134
+ split_portfolio['SG'].map(player_salary_dict),
135
+ split_portfolio['SF'].map(player_salary_dict),
136
+ split_portfolio['PF'].map(player_salary_dict),
137
+ split_portfolio['C'].map(player_salary_dict),
138
+ split_portfolio['G'].map(player_salary_dict),
139
+ split_portfolio['F'].map(player_salary_dict),
140
+ split_portfolio['UTIL'].map(player_salary_dict)])
141
+
142
+ split_portfolio['Projection'] = sum([split_portfolio['PG'].map(player_proj_dict),
143
+ split_portfolio['SG'].map(player_proj_dict),
144
+ split_portfolio['SF'].map(player_proj_dict),
145
+ split_portfolio['PF'].map(player_proj_dict),
146
+ split_portfolio['C'].map(player_proj_dict),
147
+ split_portfolio['G'].map(player_proj_dict),
148
+ split_portfolio['F'].map(player_proj_dict),
149
+ split_portfolio['UTIL'].map(player_proj_dict)])
150
+
151
+
152
+ split_portfolio['Ownership'] = sum([split_portfolio['PG'].map(player_own_dict),
153
+ split_portfolio['SG'].map(player_own_dict),
154
+ split_portfolio['SF'].map(player_own_dict),
155
+ split_portfolio['PF'].map(player_own_dict),
156
+ split_portfolio['C'].map(player_own_dict),
157
+ split_portfolio['G'].map(player_own_dict),
158
+ split_portfolio['F'].map(player_own_dict),
159
+ split_portfolio['UTIL'].map(player_own_dict)])
160
+
161
+ st.table(split_portfolio.head(10))
162
+
163
+ except:
164
+ split_portfolio = portfolio_dataframe
165
+
166
+ split_portfolio['Salary'] = sum([split_portfolio['PG'].map(player_salary_dict),
167
+ split_portfolio['SG'].map(player_salary_dict),
168
+ split_portfolio['SF'].map(player_salary_dict),
169
+ split_portfolio['PF'].map(player_salary_dict),
170
+ split_portfolio['C'].map(player_salary_dict),
171
+ split_portfolio['G'].map(player_salary_dict),
172
+ split_portfolio['F'].map(player_salary_dict),
173
+ split_portfolio['UTIL'].map(player_salary_dict)])
174
+
175
+ split_portfolio['Projection'] = sum([split_portfolio['PG'].map(player_proj_dict),
176
+ split_portfolio['SG'].map(player_proj_dict),
177
+ split_portfolio['SF'].map(player_proj_dict),
178
+ split_portfolio['PF'].map(player_proj_dict),
179
+ split_portfolio['C'].map(player_proj_dict),
180
+ split_portfolio['G'].map(player_proj_dict),
181
+ split_portfolio['F'].map(player_proj_dict),
182
+ split_portfolio['UTIL'].map(player_proj_dict)])
183
+
184
+
185
+ split_portfolio['Ownership'] = sum([split_portfolio['PG'].map(player_own_dict),
186
+ split_portfolio['SG'].map(player_own_dict),
187
+ split_portfolio['SF'].map(player_own_dict),
188
+ split_portfolio['PF'].map(player_own_dict),
189
+ split_portfolio['C'].map(player_own_dict),
190
+ split_portfolio['G'].map(player_own_dict),
191
+ split_portfolio['F'].map(player_own_dict),
192
+ split_portfolio['UTIL'].map(player_own_dict)])
193
+
194
+ display_portfolio = split_portfolio[['PG', 'SG', 'SF', 'PF', 'C', 'G', 'F', 'UTIL', 'Salary', 'Projection', 'Ownership']]
195
+ st.session_state.display_portfolio = display_portfolio
196
+ hold_portfolio = display_portfolio.sort_values(by='Projection', ascending=False)
197
+
198
+ st.session_state.player_freq = pd.DataFrame(np.column_stack(np.unique(st.session_state.display_portfolio.iloc[:,0:8].values, return_counts=True)),
199
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
200
+ st.session_state.player_freq['Freq'] = st.session_state.player_freq['Freq'] / len(st.session_state.display_portfolio)
201
+ st.session_state.player_freq = st.session_state.player_freq.set_index('Player')
202
+
203
+ gc.collect()
204
+
205
+ with tab2:
206
+ with st.container():
207
+ hold_container = st.empty()
208
+ col1, col2, col3 = st.columns([3, 3, 3])
209
+ with col1:
210
+ if st.button("Load/Reset Data", key='reset1'):
211
+ for key in st.session_state.keys():
212
+ del st.session_state[key]
213
+ display_portfolio = hold_portfolio
214
+ st.session_state.display_portfolio = display_portfolio
215
+ st.session_state.player_freq = pd.DataFrame(np.column_stack(np.unique(st.session_state.display_portfolio.iloc[:,0:8].values, return_counts=True)),
216
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
217
+ st.session_state.player_freq['Freq'] = st.session_state.player_freq['Freq'] / len(st.session_state.display_portfolio)
218
+ st.session_state.player_freq = st.session_state.player_freq.set_index('Player')
219
+ with col2:
220
+ if st.button("Trim Lineups", key='trim1'):
221
+ max_proj = 10000
222
+ max_own = display_portfolio['Ownership'].iloc[0]
223
+ x = 0
224
+ for index, row in display_portfolio.iterrows():
225
+ if row['Ownership'] > max_own:
226
+ display_portfolio.drop(index, inplace=True)
227
+ elif row['Ownership'] <= max_own:
228
+ max_own = row['Ownership']
229
+ st.session_state.display_portfolio = display_portfolio
230
+ st.session_state.player_freq = pd.DataFrame(np.column_stack(np.unique(st.session_state.display_portfolio.iloc[:,0:8].values, return_counts=True)),
231
+ columns=['Player','Freq']).sort_values('Freq', ascending=False).reset_index(drop=True)
232
+ st.session_state.player_freq['Freq'] = st.session_state.player_freq['Freq'] / len(st.session_state.display_portfolio)
233
+ st.session_state.player_freq = st.session_state.player_freq.set_index('Player')
234
+ with col3:
235
+ player_check = st.selectbox('Select player to create comps', options = proj_dataframe['Player'].unique(), key='dk_player')
236
+ if st.button('Simulate appropriate pivots'):
237
+ with hold_container:
238
+
239
+ working_roo = proj_dataframe
240
+ working_roo.rename(columns={"Minutes Proj": "Minutes_Proj"}, inplace = True)
241
+ own_dict = dict(zip(working_roo.Player, working_roo.Own))
242
+ min_dict = dict(zip(working_roo.Player, working_roo.Minutes_Proj))
243
+ team_dict = dict(zip(working_roo.Player, working_roo.Team))
244
+ total_sims = 1000
245
+
246
+ player_var = working_roo.loc[working_roo['Player'] == player_check]
247
+ player_var = player_var.reset_index()
248
+
249
+ working_roo = working_roo.loc[(working_roo['Salary'] >= player_var['Salary'][0] - 300) & (working_roo['Salary'] <= player_var['Salary'][0] + 300)]
250
+ working_roo = working_roo.loc[(working_roo['Median'] >= player_var['Median'][0] - 3) & (working_roo['Median'] <= player_var['Median'][0] + 3)]
251
+
252
+ flex_file = working_roo[['Player', 'Position', 'Salary', 'Median', 'Minutes_Proj']]
253
+ flex_file['Floor'] = (flex_file['Median'] * .25) + (flex_file['Minutes_Proj'] * .25)
254
+ flex_file['Ceiling'] = flex_file['Median'] + 10 + (flex_file['Minutes_Proj'] * .25)
255
+ flex_file['STD'] = (flex_file['Median']/4)
256
+ flex_file = flex_file[['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD']]
257
+ hold_file = flex_file
258
+ overall_file = flex_file
259
+ salary_file = flex_file
260
+
261
+ overall_players = overall_file[['Player']]
262
+
263
+ for x in range(0,total_sims):
264
+ salary_file[x] = salary_file['Salary']
265
+
266
+ salary_file=salary_file.drop(['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)
267
+ salary_file.astype('int').dtypes
268
+
269
+ salary_file = salary_file.div(1000)
270
+
271
+ for x in range(0,total_sims):
272
+ overall_file[x] = np.random.normal(overall_file['Median'],overall_file['STD'])
273
+
274
+ overall_file=overall_file.drop(['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'STD'], axis=1)
275
+ overall_file.astype('int').dtypes
276
+
277
+ players_only = hold_file[['Player']]
278
+ raw_lineups_file = players_only
279
+
280
+ for x in range(0,total_sims):
281
+ maps_dict = {'proj_map':dict(zip(hold_file.Player,hold_file[x]))}
282
+ raw_lineups_file[x] = sum([raw_lineups_file['Player'].map(maps_dict['proj_map'])])
283
+ players_only[x] = raw_lineups_file[x].rank(ascending=False)
284
+
285
+ players_only=players_only.drop(['Player'], axis=1)
286
+ players_only.astype('int').dtypes
287
+
288
+ salary_2x_check = (overall_file - (salary_file*4))
289
+ salary_3x_check = (overall_file - (salary_file*5))
290
+ salary_4x_check = (overall_file - (salary_file*6))
291
+ gpp_check = (overall_file - ((salary_file*5)+10))
292
+
293
+ players_only['Average_Rank'] = players_only.mean(axis=1)
294
+ players_only['Top_finish'] = players_only[players_only == 1].count(axis=1)/total_sims
295
+ players_only['Top_5_finish'] = players_only[players_only <= 5].count(axis=1)/total_sims
296
+ players_only['Top_10_finish'] = players_only[players_only <= 10].count(axis=1)/total_sims
297
+ players_only['20+%'] = overall_file[overall_file >= 20].count(axis=1)/float(total_sims)
298
+ players_only['3x%'] = salary_2x_check[salary_2x_check >= 1].count(axis=1)/float(total_sims)
299
+ players_only['4x%'] = salary_3x_check[salary_3x_check >= 1].count(axis=1)/float(total_sims)
300
+ players_only['5x%'] = salary_4x_check[salary_4x_check >= 1].count(axis=1)/float(total_sims)
301
+ players_only['GPP%'] = salary_4x_check[gpp_check >= 1].count(axis=1)/float(total_sims)
302
+
303
+ players_only['Player'] = hold_file[['Player']]
304
+
305
+ final_outcomes = players_only[['Player', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '3x%', '4x%', '5x%', 'GPP%']]
306
+
307
+ final_Proj = pd.merge(hold_file, final_outcomes, on="Player")
308
+ final_Proj = final_Proj[['Player', 'Position', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '3x%', '4x%', '5x%', 'GPP%']]
309
+
310
+ final_Proj['Own'] = final_Proj['Player'].map(own_dict)
311
+ final_Proj['Minutes Proj'] = final_Proj['Player'].map(min_dict)
312
+ final_Proj['Team'] = final_Proj['Player'].map(team_dict)
313
+ final_Proj['Own'] = final_Proj['Own'].astype('float')
314
+ final_Proj['Projection Rank'] = final_Proj.Top_finish.rank(pct = True)
315
+ final_Proj['Own Rank'] = final_Proj.Own.rank(pct = True)
316
+ final_Proj['LevX'] = (final_Proj['Projection Rank'] - final_Proj['Own Rank']) * 100
317
+ final_Proj['ValX'] = ((final_Proj[['4x%', '5x%']].mean(axis=1))*100) + final_Proj['LevX']
318
+ final_Proj['ValX'] = np.where(final_Proj['ValX'] > 100, 100, final_Proj['ValX'])
319
+ final_Proj['ValX'] = np.where(final_Proj['ValX'] < 0, 0, final_Proj['ValX'])
320
+
321
+ final_Proj = final_Proj[['Player', 'Minutes Proj', 'Position', 'Team', 'Salary', 'Floor', 'Median', 'Ceiling', 'Top_finish', 'Top_5_finish', 'Top_10_finish', '20+%', '3x%', '4x%', '5x%', 'GPP%', 'Own', 'LevX', 'ValX']]
322
+ final_Proj = final_Proj.sort_values(by='Median', ascending=False)
323
+ final_Proj['Player_swap'] = player_check
324
+ st.session_state.final_Proj = final_Proj
325
+
326
+ hold_container = st.empty()
327
+ with st.container():
328
+ col1, col2 = st.columns([7, 2])
329
+ with col1:
330
+ if 'display_portfolio' in st.session_state:
331
+ st.dataframe(st.session_state.display_portfolio.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
332
+
333
+ # with display_container:
334
+ # display_container = st.empty()
335
+ # if 'final_Proj' in st.session_state:
336
+ # st.dataframe(st.session_state.final_Proj.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
337
+ with col2:
338
+ if 'player_freq' in st.session_state:
339
+ st.dataframe(st.session_state.player_freq.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)