From 1980a308b5dd9b48bb82236b15bccb56ab993b21 Mon Sep 17 00:00:00 2001 From: jamieveitch Date: Sun, 18 Dec 2022 20:14:58 +0000 Subject: [PATCH] introduced game type filter --- analysis/utilities.py | 14 +++++++++- spreadsheet/webapp.py | 65 +++++++++++++++++++++++++++---------------- 2 files changed, 54 insertions(+), 25 deletions(-) diff --git a/analysis/utilities.py b/analysis/utilities.py index 1a2015a..5c7e0c0 100644 --- a/analysis/utilities.py +++ b/analysis/utilities.py @@ -55,4 +55,16 @@ def player_names(games: pd.DataFrame) -> dict: user_id_frame = user_id_frame.reset_index()[['uid', 'name']] user_id_dict = user_id_frame.set_index('uid').squeeze().to_dict() - return user_id_dict \ No newline at end of file + return user_id_dict + + +def get_game_type(games: pd.DataFrame) -> pd.DataFrame: + """ + calculate the team size for a specific round and add it as a column + :param games: + :return: + """ + team_size = games.groupby(['matchID', 'round', 'team'])['name'].count() + team_size = team_size.rename('team_size').reset_index(level=[1, 2])['team_size'] + + return pd.merge(games, team_size, left_index=True, right_index=True).reset_index() diff --git a/spreadsheet/webapp.py b/spreadsheet/webapp.py index a98718f..26a9cac 100644 --- a/spreadsheet/webapp.py +++ b/spreadsheet/webapp.py @@ -5,6 +5,7 @@ from database.mongo import load_database from analysis.preprocess import preprocess +from analysis.utilities import get_game_type def page_setup() -> None: @@ -13,7 +14,7 @@ def page_setup() -> None: """ st.set_page_config( page_title="Stats Explorer", - page_icon='https://avatars.githubusercontent.com/u/94710688?s=200&v=4' + page_icon="https://avatars.githubusercontent.com/u/94710688?s=200&v=4" ) title_image, title_text = st.columns(2) @@ -40,6 +41,7 @@ def load_game_data() -> pd.DataFrame: return load_database() ranked_games = preprocess(load_game_data()) + ranked_games = get_game_type(ranked_games) start_date, end_date = st.columns(2) @@ -55,55 +57,69 @@ def load_game_data() -> pd.DataFrame: st.date_input("End Date", key="end_date", help="The end date of the query") st.multiselect( - label='Group Columns', - options=ranked_games.columns[ranked_games.dtypes == object], - key='group_columns' + label="Filter Match Type", + options=sorted(ranked_games.team_size.unique()), + default=sorted(ranked_games.team_size.unique()), + key="match_type", + format_func=lambda match: f"{match}v{match}", ) st.multiselect( - label='Data Columns', - options=ranked_games.columns[ranked_games.dtypes != object], - key='data_columns' + label="Group Columns", + options=sorted(ranked_games.columns[ranked_games.dtypes == object]), + key="group_columns" + ) + st.multiselect( + label="Data Columns", + options=sorted(ranked_games.columns[ranked_games.dtypes != object]), + key="data_columns" ) st.selectbox( - label='Aggregation Method', - options=['sum', 'mean', 'std', 'max', 'min'], - key='agg_func', + label="Aggregation Method", + options=["sum", "mean", "std", "max", "min"], + key="agg_func", + help="sum = all values added together, mean = average per round, std = consistency (high = inconsistent)" + "max = the maximum value achieved, min = the minimum value achieved" ) st.multiselect( - label='View Players (Optional)', - options=ranked_games.name.unique(), - key='players' + label="View Players (Optional)", + options=sorted(ranked_games.name.unique()), + key="players" ) if not state.group_columns or not state.data_columns: st.stop() ranked_games = ranked_games[ - (ranked_games['matchTimestamp'] > state.start_date.strftime("%Y-%m-%d")) & - (ranked_games['matchTimestamp'] < state.end_date.strftime("%Y-%m-%d")) + (ranked_games["matchTimestamp"] > state.start_date.strftime("%Y-%m-%d")) & + (ranked_games["matchTimestamp"] < state.end_date.strftime("%Y-%m-%d")) ] + if not state.match_type: + st.write("please include a match type") + st.stop() + + ranked_games = ranked_games[ranked_games.team_size.isin(state.match_type)] view_games = ranked_games.groupby(state.group_columns)[state.data_columns].agg(state.agg_func) round_count = ranked_games.groupby( - state.group_columns)['name'].count().squeeze().astype(int).rename('rounds_played') + state.group_columns)["name"].count().squeeze().astype(int).rename("rounds_played") view_games = pd.concat([view_games, round_count], axis=1) view_games = round(view_games, 2) st.slider( - label='Min Rounds Played', + label="Min Rounds Played", value=0, min_value=0, max_value=int(view_games["rounds_played"].max()), step=1, - key='rounds_min' + key="rounds_min" ) - wins = ranked_games.groupby(state.group_columns)['result'].value_counts().loc[ + wins = ranked_games.groupby(state.group_columns)["result"].value_counts().loc[ ranked_games.groupby( - state.group_columns)['result'].value_counts().index.get_level_values(-1) == 'Win'].droplevel(-1) - win_loss = round(wins.div(view_games['rounds_played']), 2).rename('win_loss') + state.group_columns)["result"].value_counts().index.get_level_values(-1) == "Win"].droplevel(-1) + win_loss = round(wins.div(view_games["rounds_played"]), 2).rename("win_loss") view_games = pd.concat([view_games, win_loss.fillna(0.0)], axis=1) - view_games = view_games[view_games['rounds_played'] > state.rounds_min] + view_games = view_games[view_games["rounds_played"] > state.rounds_min] view_games = view_games.reset_index() if not state.players: @@ -114,14 +130,15 @@ def load_game_data() -> pd.DataFrame: else: try: st.dataframe( - view_games.set_index('name').loc[state.players].reset_index(), + view_games.set_index("name").loc[state.players].reset_index(), use_container_width=True ) except KeyError: st.text("no datapoints meet the filter requirements") + st.text("if you want to filter on player name, make sure to include 'name' in Group Columns") -if __name__ == '__main__': +if __name__ == "__main__": page_setup() view_data()