James McCool commited on
Commit
896d108
·
1 Parent(s): a6e2b8d

Enhance player data handling in app.py by introducing a new data type selection feature. Users can now choose between "Team" and "Player" data types, allowing for more flexible data analysis. Updated the player data initialization function to support player-specific statistics, including average performance metrics based on game outcomes. This change improves the overall functionality and user experience of the application.

Browse files
Files changed (1) hide show
  1. app.py +226 -6
app.py CHANGED
@@ -27,6 +27,8 @@ def init_conn():
27
  db, team_names, player_names, min_date, max_date = init_conn()
28
 
29
  display_formats = {'wKill%': '{:.2%}', 'wDeath%': '{:.2%}', 'wAssist%': '{:.2%}', 'lKill%': '{:.2%}', 'lDeath%': '{:.2%}', 'lAssist%': '{:.2%}'}
 
 
30
 
31
  # Create sidebar container for options
32
  with st.sidebar:
@@ -59,13 +61,26 @@ with st.sidebar:
59
  max_value=max_date.date()
60
  )
61
 
 
 
 
 
 
 
 
62
  col1, col2 = st.columns(2)
63
  with col1:
64
- selected_team = st.selectbox(
65
- "Select Team",
66
- options=team_names,
67
- index=team_names.index("T1") if "T1" in team_names else 0
68
- )
 
 
 
 
 
 
69
  with col2:
70
  selected_opponent = st.selectbox(
71
  "Select Opponent",
@@ -350,8 +365,213 @@ def init_team_data(team, opponent, win_loss_settings, kill_predictions, death_pr
350
 
351
  return overall_team_data.dropna().set_index('playername'), opp_boosts, results_dict
352
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
353
  if st.button("Run"):
354
- team_data, opp_boost, results_dict = init_team_data(selected_team, selected_opponent, win_loss_settings, kill_predictions, death_predictions, start_date, end_date)
 
 
 
355
 
356
  player_summary = pd.DataFrame()
357
  for game_num in range(game_count):
 
27
  db, team_names, player_names, min_date, max_date = init_conn()
28
 
29
  display_formats = {'wKill%': '{:.2%}', 'wDeath%': '{:.2%}', 'wAssist%': '{:.2%}', 'lKill%': '{:.2%}', 'lDeath%': '{:.2%}', 'lAssist%': '{:.2%}'}
30
+ leagues = ['AL', 'CBLOL', 'GLL', 'HM', 'LCK', 'LCS', 'LEC', 'LFL', 'LLA', 'LPL', 'LPLOL', 'LVP SL', 'MSI', 'PCS', 'PGN', 'PRM', 'TCL', 'VCS', 'LTAN', 'LTAS',
31
+ 'LLA', 'LPL', 'LPLOL', 'LVP SL', 'MSI', 'PCS', 'PGN', 'PRM', 'TCL', 'VCS', 'LTAN', 'LTAS']
32
 
33
  # Create sidebar container for options
34
  with st.sidebar:
 
61
  max_value=max_date.date()
62
  )
63
 
64
+ # Date filtering options
65
+ st.subheader("Data Type")
66
+ data_type = st.radio(
67
+ "Select Data Type",
68
+ ["Team", "Player"]
69
+ )
70
+
71
  col1, col2 = st.columns(2)
72
  with col1:
73
+ if data_type == "Player":
74
+ selected_players = st.multiselect(
75
+ "Select Players",
76
+ options=player_names
77
+ )
78
+ else:
79
+ selected_team = st.selectbox(
80
+ "Select Team",
81
+ options=team_names,
82
+ index=team_names.index("T1") if "T1" in team_names else 0
83
+ )
84
  with col2:
85
  selected_opponent = st.selectbox(
86
  "Select Opponent",
 
365
 
366
  return overall_team_data.dropna().set_index('playername'), opp_boosts, results_dict
367
 
368
+ @st.cache_data(ttl = 60)
369
+ def init_player_data(players, opponent, win_loss_settings, kill_predictions, death_predictions, start_date, end_date):
370
+ game_count = len(kill_predictions)
371
+ overall_team_data = pd.DataFrame(columns = ['playername', 'teamname', 'position', 'Kill_Proj', 'Death_Proj', 'Assist_Proj', 'CS_Proj'])
372
+ # Convert date objects to datetime strings in the correct format
373
+ start_datetime = datetime.combine(start_date, datetime.min.time()).strftime("%Y-%m-%d %H:%M:%S")
374
+ end_datetime = datetime.combine(end_date, datetime.max.time()).strftime("%Y-%m-%d %H:%M:%S")
375
+
376
+ collection = db["gamelogs"]
377
+ cursor = collection.find({"playername": players, "date": {"$gte": start_datetime, "$lte": end_datetime}})
378
+ raw_display = pd.DataFrame(list(cursor))
379
+
380
+ cursor = collection.find({"date": {"$gte": start_datetime, "$lte": end_datetime}})
381
+ raw_opponent = pd.DataFrame(list(cursor))
382
+
383
+ tables_to_loop = [raw_display, raw_opponent]
384
+
385
+ for loop in range(len(tables_to_loop)):
386
+ tables = tables_to_loop[loop]
387
+ calc_columns = ['kills', 'deaths', 'assists', 'total_cs']
388
+ league_pos_win_stats = {}
389
+ league_pos_loss_stats = {}
390
+ Opponent_pos_win_allowed_stats = {}
391
+ Opponent_pos_loss_allowed_stats = {}
392
+ playername_win_stats = {}
393
+ playername_loss_stats = {}
394
+ teamname_win_stats = {}
395
+ teamname_loss_stats = {}
396
+
397
+ if loop == 0:
398
+
399
+ for stats in calc_columns:
400
+ playername_win_stats[stats] = tables[tables['result'] == 1].groupby(['playername'])[stats].mean().to_dict()
401
+ playername_loss_stats[stats] = tables[tables['result'] == 0].groupby(['playername'])[stats].mean().to_dict()
402
+ teamname_win_stats[stats] = tables[(tables['result'] == 1) & (tables['position'] == 'team')].groupby(['teamname'])[stats].mean().to_dict()
403
+ teamname_loss_stats[stats] = tables[(tables['result'] == 0) & (tables['position'] == 'team')].groupby(['teamname'])[stats].mean().to_dict()
404
+
405
+ for stat in calc_columns:
406
+
407
+ column_name = f'playername_avg_{stat}_win'
408
+ tables[column_name] = tables.apply(
409
+ lambda row: playername_win_stats[stat].get(row['playername'], 0),
410
+ axis=1
411
+ )
412
+
413
+ column_name = f'playername_avg_{stat}_loss'
414
+ tables[column_name] = tables.apply(
415
+ lambda row: playername_loss_stats[stat].get(row['playername'], 0),
416
+ axis=1
417
+ )
418
+
419
+ column_name = f'teamname_avg_{stat}_win'
420
+ tables[column_name] = tables.apply(
421
+ lambda row: teamname_win_stats[stat].get(row['teamname'], 0),
422
+ axis=1
423
+ )
424
+
425
+ column_name = f'teamname_avg_{stat}_loss'
426
+ tables[column_name] = tables.apply(
427
+ lambda row: teamname_loss_stats[stat].get(row['teamname'], 0),
428
+ axis=1
429
+ )
430
+
431
+ tables['playername_avg_kill_share_win'] = tables['playername_avg_kills_win'] / tables['teamname_avg_kills_win']
432
+ tables['playername_avg_death_share_win'] = tables['playername_avg_deaths_win'] / tables['teamname_avg_deaths_win']
433
+ tables['playername_avg_assist_share_win'] = tables['playername_avg_assists_win'] / tables['teamname_avg_kills_win']
434
+ tables['playername_avg_cs_share_win'] = tables['playername_avg_total_cs_win'] / tables['teamname_avg_total_cs_win']
435
+ tables['playername_avg_kill_share_loss'] = tables['playername_avg_kills_loss'] / tables['teamname_avg_kills_loss']
436
+ tables['playername_avg_death_share_loss'] = tables['playername_avg_deaths_loss'] / tables['teamname_avg_deaths_loss']
437
+ tables['playername_avg_assist_share_loss'] = tables['playername_avg_assists_loss'] / tables['teamname_avg_kills_loss']
438
+ tables['playername_avg_cs_share_loss'] = tables['playername_avg_total_cs_loss'] / tables['teamname_avg_total_cs_loss']
439
+ player_tables = tables
440
+
441
+ else:
442
+
443
+ for stats in calc_columns:
444
+ league_pos_win_stats[stats] = {
445
+ league: group.groupby('position')[stats].mean().to_dict()
446
+ for league, group in tables[tables['result'] == 1].groupby('league')
447
+ }
448
+ league_pos_loss_stats[stats] = {
449
+ league: group.groupby('position')[stats].mean().to_dict()
450
+ for league, group in tables[tables['result'] == 0].groupby('league')
451
+ }
452
+
453
+ Opponent_pos_win_allowed_stats[stats] = {
454
+ opponent: group.groupby('position')[stats].mean().to_dict()
455
+ for opponent, group in tables[tables['result'] == 1].groupby('Opponent')
456
+ }
457
+ Opponent_pos_loss_allowed_stats[stats] = {
458
+ opponent: group.groupby('position')[stats].mean().to_dict()
459
+ for opponent, group in tables[tables['result'] == 0].groupby('Opponent')
460
+ }
461
+
462
+ for stat in calc_columns:
463
+
464
+ column_name = f'league_pos_avg_{stat}_win'
465
+ tables[column_name] = tables.apply(
466
+ lambda row: league_pos_win_stats[stat].get(row['league'], {}).get(row['position'], 0),
467
+ axis=1
468
+ )
469
+
470
+ column_name = f'league_pos_avg_{stat}_loss'
471
+ tables[column_name] = tables.apply(
472
+ lambda row: league_pos_loss_stats[stat].get(row['league'], {}).get(row['position'], 0),
473
+ axis=1
474
+ )
475
+
476
+ column_name = f'Opponent_pos_avg_{stat}_allowed_win'
477
+ tables[column_name] = tables.apply(
478
+ lambda row: Opponent_pos_win_allowed_stats[stat].get(row['Opponent'], {}).get(row['position'], 0),
479
+ axis=1
480
+ )
481
+
482
+ column_name = f'Opponent_pos_avg_{stat}_allowed_loss'
483
+ tables[column_name] = tables.apply(
484
+ lambda row: Opponent_pos_loss_allowed_stats[stat].get(row['Opponent'], {}).get(row['position'], 0),
485
+ axis=1
486
+ )
487
+
488
+ tables = tables[tables['Opponent'] == opponent]
489
+
490
+ tables['overall_win_kills_boost_pos'] = tables['Opponent_pos_avg_kills_allowed_win'] / tables['league_pos_avg_kills_win']
491
+ tables['overall_win_deaths_boost_pos'] = tables['Opponent_pos_avg_deaths_allowed_win'] / tables['league_pos_avg_deaths_win']
492
+ tables['overall_win_assists_boost_pos'] = tables['Opponent_pos_avg_assists_allowed_win'] / tables['league_pos_avg_assists_win']
493
+ tables['overall_win_total_cs_boost_pos'] = tables['Opponent_pos_avg_total_cs_allowed_win'] / tables['league_pos_avg_total_cs_win']
494
+ tables['overall_loss_kills_boost_pos'] = tables['Opponent_pos_avg_kills_allowed_loss'] / tables['league_pos_avg_kills_loss']
495
+ tables['overall_loss_deaths_boost_pos'] = tables['Opponent_pos_avg_deaths_allowed_loss'] / tables['league_pos_avg_deaths_loss']
496
+ tables['overall_loss_assists_boost_pos'] = tables['Opponent_pos_avg_assists_allowed_loss'] / tables['league_pos_avg_assists_loss']
497
+ tables['overall_loss_total_cs_boost_pos'] = tables['Opponent_pos_avg_total_cs_allowed_loss'] / tables['league_pos_avg_total_cs_loss']
498
+
499
+ opp_tables = tables
500
+ opp_pos_kills_boost_win = dict(zip(opp_tables['position'], opp_tables['overall_win_kills_boost_pos']))
501
+ opp_pos_deaths_boost_win = dict(zip(opp_tables['position'], opp_tables['overall_win_deaths_boost_pos']))
502
+ opp_pos_assists_boost_win = dict(zip(opp_tables['position'], opp_tables['overall_win_assists_boost_pos']))
503
+ opp_pos_cs_boost_win = dict(zip(opp_tables['position'], opp_tables['overall_win_total_cs_boost_pos']))
504
+ opp_pos_kills_boost_loss = dict(zip(opp_tables['position'], opp_tables['overall_loss_kills_boost_pos']))
505
+ opp_pos_deaths_boost_loss = dict(zip(opp_tables['position'], opp_tables['overall_loss_deaths_boost_pos']))
506
+ opp_pos_assists_boost_loss = dict(zip(opp_tables['position'], opp_tables['overall_loss_assists_boost_pos']))
507
+ opp_pos_cs_boost_loss = dict(zip(opp_tables['position'], opp_tables['overall_loss_total_cs_boost_pos']))
508
+ opp_boosts = pd.DataFrame({
509
+ 'opp_pos_kills_boost_win': opp_pos_kills_boost_win,
510
+ 'opp_pos_deaths_boost_win': opp_pos_deaths_boost_win,
511
+ 'opp_pos_assists_boost_win': opp_pos_assists_boost_win,
512
+ 'opp_pos_cs_boost_win': opp_pos_cs_boost_win,
513
+ 'opp_pos_kills_boost_loss': opp_pos_kills_boost_loss,
514
+ 'opp_pos_deaths_boost_loss': opp_pos_deaths_boost_loss,
515
+ 'opp_pos_assists_boost_loss': opp_pos_assists_boost_loss,
516
+ 'opp_pos_cs_boost_loss': opp_pos_cs_boost_loss
517
+ }).set_index(pd.Index(list(opp_pos_kills_boost_win.keys()), name='position'))
518
+
519
+ results_dict = {}
520
+
521
+ for game in range(game_count):
522
+ if kill_predictions[game] > 0:
523
+ working_tables = player_tables[['playername', 'teamname', 'position', 'playername_avg_kill_share_win', 'playername_avg_death_share_win','playername_avg_assist_share_win',
524
+ 'playername_avg_total_cs_win', 'playername_avg_kill_share_loss', 'playername_avg_death_share_loss', 'playername_avg_assist_share_loss', 'playername_avg_total_cs_loss']]
525
+ working_tables = working_tables.rename(columns = {'playername_avg_kill_share_win': 'wKill%', 'playername_avg_death_share_win': 'wDeath%', 'playername_avg_assist_share_win': 'wAssist%',
526
+ 'playername_avg_total_cs_win': 'wCS', 'playername_avg_kill_share_loss': 'lKill%', 'playername_avg_death_share_loss': 'lDeath%',
527
+ 'playername_avg_assist_share_loss': 'lAssist%', 'playername_avg_total_cs_loss': 'lCS'})
528
+ team_data = working_tables.drop_duplicates(subset = ['playername'])
529
+
530
+ if win_loss_settings[game] == "Win":
531
+ team_data['Kill_Proj'] = team_data.apply(lambda row: row['wKill%'] * opp_pos_kills_boost_win.get(row['position'], 1), axis=1) * kill_predictions[game]
532
+ team_data['Death_Proj'] = team_data.apply(lambda row: row['wDeath%'] * opp_pos_deaths_boost_win.get(row['position'], 1), axis=1) * death_predictions[game]
533
+ team_data['Assist_Proj'] = team_data.apply(lambda row: row['wAssist%'] * opp_pos_assists_boost_win.get(row['position'], 1), axis=1) * kill_predictions[game]
534
+ team_data['CS_Proj'] = team_data.apply(lambda row: row['wCS'] * opp_pos_cs_boost_win.get(row['position'], 1), axis=1)
535
+ team_data = team_data[['playername', 'teamname', 'position', 'Kill_Proj', 'Death_Proj', 'Assist_Proj', 'CS_Proj']]
536
+ else:
537
+ team_data['Kill_Proj'] = team_data.apply(lambda row: row['lKill%'] * opp_pos_kills_boost_loss.get(row['position'], 1), axis=1) * kill_predictions[game]
538
+ team_data['Death_Proj'] = team_data.apply(lambda row: row['lDeath%'] * opp_pos_deaths_boost_loss.get(row['position'], 1), axis=1) * death_predictions[game]
539
+ team_data['Assist_Proj'] = team_data.apply(lambda row: row['lAssist%'] * opp_pos_assists_boost_loss.get(row['position'], 1), axis=1) * kill_predictions[game]
540
+ team_data['CS_Proj'] = team_data.apply(lambda row: row['lCS'] * opp_pos_cs_boost_loss.get(row['position'], 1), axis=1)
541
+ team_data = team_data[['playername', 'teamname', 'position', 'Kill_Proj', 'Death_Proj', 'Assist_Proj', 'CS_Proj']]
542
+ else:
543
+ working_tables = player_tables[['playername', 'teamname', 'position', 'playername_avg_kills_win', 'playername_avg_deaths_win', 'playername_avg_assists_win', 'playername_avg_total_cs_win',
544
+ 'playername_avg_kills_loss', 'playername_avg_deaths_loss', 'playername_avg_assists_loss', 'playername_avg_total_cs_loss']]
545
+ working_tables = working_tables.rename(columns = {'playername_avg_kills_win': 'wKill%', 'playername_avg_deaths_win': 'wDeath%', 'playername_avg_assists_win': 'wAssist%',
546
+ 'playername_avg_total_cs_win': 'wCS', 'playername_avg_kills_loss': 'lKill%', 'playername_avg_deaths_loss': 'lDeath%',
547
+ 'playername_avg_assists_loss': 'lAssist%', 'playername_avg_total_cs_loss': 'lCS'})
548
+ team_data = working_tables.drop_duplicates(subset = ['playername'])
549
+
550
+ if win_loss_settings[game] == "Win":
551
+ team_data['Kill_Proj'] = team_data.apply(lambda row: row['wKill%'] * opp_pos_kills_boost_win.get(row['position'], 1), axis=1)
552
+ team_data['Death_Proj'] = team_data.apply(lambda row: row['wDeath%'] * opp_pos_deaths_boost_win.get(row['position'], 1), axis=1)
553
+ team_data['Assist_Proj'] = team_data.apply(lambda row: row['wAssist%'] * opp_pos_assists_boost_win.get(row['position'], 1), axis=1)
554
+ team_data['CS_Proj'] = team_data.apply(lambda row: row['wCS'] * opp_pos_cs_boost_win.get(row['position'], 1), axis=1)
555
+ team_data = team_data[['playername', 'teamname', 'position', 'Kill_Proj', 'Death_Proj', 'Assist_Proj', 'CS_Proj']]
556
+ else:
557
+ team_data['Kill_Proj'] = team_data.apply(lambda row: row['lKill%'] * opp_pos_kills_boost_loss.get(row['position'], 1), axis=1)
558
+ team_data['Death_Proj'] = team_data.apply(lambda row: row['lDeath%'] * opp_pos_deaths_boost_loss.get(row['position'], 1), axis=1)
559
+ team_data['Assist_Proj'] = team_data.apply(lambda row: row['lAssist%'] * opp_pos_assists_boost_loss.get(row['position'], 1), axis=1)
560
+ team_data['CS_Proj'] = team_data.apply(lambda row: row['lCS'] * opp_pos_cs_boost_loss.get(row['position'], 1), axis=1)
561
+ team_data = team_data[['playername', 'teamname', 'position', 'Kill_Proj', 'Death_Proj', 'Assist_Proj', 'CS_Proj']]
562
+
563
+ results_dict[f'game {game + 1}'] = team_data.dropna()
564
+ team_data['playername'] = team_data['playername'] + f' game {game + 1}'
565
+
566
+ overall_team_data = pd.concat([overall_team_data, team_data])
567
+
568
+ return overall_team_data.dropna().set_index('playername'), opp_boosts, results_dict
569
+
570
  if st.button("Run"):
571
+ if data_type == "Team":
572
+ team_data, opp_boost, results_dict = init_team_data(selected_team, selected_opponent, win_loss_settings, kill_predictions, death_predictions, start_date, end_date)
573
+ else:
574
+ team_data, opp_boost, results_dict = init_player_data(selected_players, selected_opponent, win_loss_settings, kill_predictions, death_predictions, start_date, end_date)
575
 
576
  player_summary = pd.DataFrame()
577
  for game_num in range(game_count):