James McCool commited on
Commit
6244ceb
·
1 Parent(s): 46e893a

Add simulation of statistical projections in app.py. Introduced a new function to simulate player statistics using a normal distribution, generating percentiles for kills, deaths, assists, and CS projections. This enhancement allows for a more comprehensive analysis of player performance by incorporating simulated data, improving the overall depth of statistical insights available in the application.

Browse files
Files changed (1) hide show
  1. app.py +52 -1
app.py CHANGED
@@ -5,6 +5,7 @@ import pandas as pd
5
  import pymongo
6
  import time
7
  from datetime import datetime, timedelta
 
8
 
9
  @st.cache_resource
10
  def init_conn():
@@ -102,6 +103,24 @@ with st.sidebar:
102
  value=5
103
  )
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  @st.cache_data(ttl = 60)
106
  def init_team_data(team, opponent, win_loss, kill_prediction, death_prediction, start_date, end_date):
107
 
@@ -297,8 +316,40 @@ def init_team_data(team, opponent, win_loss, kill_prediction, death_prediction,
297
 
298
  if st.button("Run"):
299
  team_data, opp_boost = init_team_data(selected_team, selected_opponent, win_loss, kill_prediction, death_prediction, start_date, end_date)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
300
  tab1, tab2 = st.tabs(["Team Data", "Opponent Data"])
301
  with tab1:
302
  st.dataframe(team_data.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(display_formats, precision=2), use_container_width = True)
303
  with tab2:
304
- st.dataframe(opp_boost.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
 
 
 
5
  import pymongo
6
  import time
7
  from datetime import datetime, timedelta
8
+ from scipy import stats
9
 
10
  @st.cache_resource
11
  def init_conn():
 
103
  value=5
104
  )
105
 
106
+ @st.cache_data(ttl = 60)
107
+ def simulate_stats(row, num_sims=1000):
108
+ """Simulate stats using normal distribution"""
109
+ # Using coefficient of variation of 0.3 to generate reasonable standard deviations
110
+ cv = 0.3
111
+ percentiles = [10, 25, 50, 75, 90]
112
+
113
+ results = {}
114
+ for stat in ['Kill_Proj', 'Death_Proj', 'Assist_Proj', 'CS_Proj']:
115
+ mean = row[stat]
116
+ std = mean * cv # Using coefficient of variation to determine std
117
+ sims = stats.norm.rvs(loc=mean, scale=std, size=num_sims)
118
+ # Ensure no negative values
119
+ sims = np.maximum(sims, 0)
120
+ results[stat] = np.percentile(sims, percentiles)
121
+
122
+ return pd.Series(results)
123
+
124
  @st.cache_data(ttl = 60)
125
  def init_team_data(team, opponent, win_loss, kill_prediction, death_prediction, start_date, end_date):
126
 
 
316
 
317
  if st.button("Run"):
318
  team_data, opp_boost = init_team_data(selected_team, selected_opponent, win_loss, kill_prediction, death_prediction, start_date, end_date)
319
+
320
+ # Create simulated percentiles
321
+ sim_results = []
322
+ for idx, row in team_data.iterrows():
323
+ percentiles = simulate_stats(row)
324
+ sim_results.append({
325
+ 'Player': idx,
326
+ 'Position': row['position'],
327
+ 'Stat': 'Kills',
328
+ 'P10': percentiles['Kill_Proj'][0],
329
+ 'P25': percentiles['Kill_Proj'][1],
330
+ 'P50': percentiles['Kill_Proj'][2],
331
+ 'P75': percentiles['Kill_Proj'][3],
332
+ 'P90': percentiles['Kill_Proj'][4]
333
+ })
334
+ # Repeat for other stats
335
+ for stat, name in [('Death_Proj', 'Deaths'), ('Assist_Proj', 'Assists'), ('CS_Proj', 'CS')]:
336
+ sim_results.append({
337
+ 'Player': idx,
338
+ 'Position': row['position'],
339
+ 'Stat': name,
340
+ 'P10': percentiles[stat][0],
341
+ 'P25': percentiles[stat][1],
342
+ 'P50': percentiles[stat][2],
343
+ 'P75': percentiles[stat][3],
344
+ 'P90': percentiles[stat][4]
345
+ })
346
+
347
+ sim_df = pd.DataFrame(sim_results)
348
+
349
  tab1, tab2 = st.tabs(["Team Data", "Opponent Data"])
350
  with tab1:
351
  st.dataframe(team_data.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(display_formats, precision=2), use_container_width = True)
352
  with tab2:
353
+ st.dataframe(opp_boost.style.background_gradient(axis=0).background_gradient(cmap='RdYlGn').format(precision=2), use_container_width = True)
354
+
355
+ st.dataframe(sim_df.style.format(precision=2), use_container_width=True)