File size: 6,231 Bytes
dd64f21 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 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 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
import os
import numpy as np
import pandas as pd
import streamlit as st
from config import DEFAULT_ICON, LEAGUE_NAME, LEAGUE_NUMBER_TEAMS
from shared_page import common_page_config
from streamlit_filter import filter_dataframe
KEEPER_DATA_URL = "../../tests/mocks/2023_keepers.csv"
HEADSHOT_DATA_URL = "../../tests/mocks/2023_player_headshots.csv"
def load_player_ids() -> pd.DataFrame:
df = pd.read_csv(r"https://raw.githubusercontent.com/dynastyprocess/data/master/files/db_playerids.csv")
df["merge_id"] = df["yahoo_id"].combine_first(df["stats_id"])
return df
def load_adp() -> pd.DataFrame:
df = pd.read_csv(r"https://raw.githubusercontent.com/dynastyprocess/data/master/files/db_fpecr_latest.csv")
df = df.loc[
df.fp_page == "/nfl/rankings/ppr-superflex-cheatsheets.php",
[
"yahoo_id",
"ecr",
"sd",
],
]
return df
def convert_ecr_to_round_val(ecr_float: float, round_offset: float = 1.0, pick_offset: float = -1.0) -> float:
# As a float, store pick 1 of round 1 as 1.0
return round_offset + (ecr_float + pick_offset) / LEAGUE_NUMBER_TEAMS
def add_opinionated_keeper_value(df: pd.DataFrame):
# Manual Hack for overranking of backup QBs
df.loc[
df["name"].isin(
[
"Teddy Bridgewater",
"Davis Mills",
"Andy Dalton",
"Tyler Huntley",
"Mike White",
"Gardner Minshew",
"Colt McCoy",
"Sam Darnold",
"Carson Wentz",
"Trey Lance",
"Taylor Heinicke",
]
),
["ecr"],
] = np.nan
df["ecr"] = df["ecr"].apply(convert_ecr_to_round_val)
# Convert sd without offset to show as pure pick diff
df["sd"] = df["sd"].apply(lambda x: convert_ecr_to_round_val(x, 0, 0))
# assumes midround keeper
# fill -99 for players that are not ranked in ecr
df["value_keeper"] = (df["keeper_cost"] + 0.5 - df["ecr"]).fillna(-99)
@st.cache_data(ttl=60 * 60 * 24)
def load_data():
data = pd.read_csv(os.path.join(os.path.dirname(__file__), KEEPER_DATA_URL), index_col=0)
# Hack to get position, replace with better position from yahoo api in future
data["position"] = data["eligible_positions"].apply(lambda x: eval(x)[0])
data.columns = data.columns.str.lower()
teams_list = sorted(list(data["team_name"].unique()))
# Merge player ids
df_player_ids = load_player_ids()
data = data.merge(df_player_ids, how="left", left_on="player_id", right_on="merge_id", suffixes=("", "_ids"))
# Merge ADP
df_adp = load_adp()
data = data.merge(df_adp, how="left", left_on="player_id", right_on="yahoo_id", suffixes=("", "_adp"))
add_opinionated_keeper_value(data)
return data, teams_list
def filtered_keeper_dataframe(data: pd.DataFrame, teams_list: list[str]):
teams_selected = st.multiselect("Team:", teams_list, placeholder="Select a user team to filter")
teams_filter = data["team_name"].isin(teams_selected) if teams_selected else data["team_name"].isin(teams_list)
eligible_options = [True, False]
is_eligible_selected = st.multiselect(
"Keeper Eligible:", eligible_options, placeholder="Select True to filter eligible only"
)
eligible_filter = (
data["eligible"].isin(is_eligible_selected) if is_eligible_selected else data["eligible"].isin(eligible_options)
)
is_advanced = st.checkbox("Show Advanced View")
id_cols = [
"team_name",
"headshot_url",
"name",
]
id_cols_advanced = [
"team",
"position",
]
cost_cols = [
"keeper_cost",
"eligible",
]
cost_cols_advanced = [
"years_eligible",
]
adp_cols: list[str] = []
adp_cols_advanced = [
"ecr",
"value_keeper",
]
if is_advanced:
show_columns = id_cols + id_cols_advanced + cost_cols + cost_cols_advanced + adp_cols + adp_cols_advanced
else:
show_columns = id_cols + cost_cols + adp_cols
data_with_filters_applied = data.loc[teams_filter & eligible_filter, show_columns]
filtered_data = filter_dataframe(data_with_filters_applied)
st.dataframe(
filtered_data,
hide_index=True,
height=35 * (len(filtered_data) + 1) + 12,
use_container_width=True,
column_config={
"team_name": st.column_config.TextColumn(label="League Team", help="Name of fantasy League team."),
"headshot_url": st.column_config.ImageColumn(label="", help="Player image"),
"name": st.column_config.TextColumn(label="Name", help="Player's name"),
"team": st.column_config.TextColumn(label="NFL Team"),
"position": st.column_config.TextColumn(label="Position", help="Player's position"),
"keeper_cost": st.column_config.NumberColumn(
label="Keeper Cost", help="Draft Round Cost to keep player. See Rules for details."
),
"eligible": st.column_config.CheckboxColumn(label="Eligible", help="Is player eligible to be keeper?"),
"years_eligible": st.column_config.NumberColumn(
label="Years Eligible",
help="Number of further consecutive seasons player can be kept (subject to maximum of 2)",
),
"ecr": st.column_config.NumberColumn(
label="ECR",
help="Player's average draft round.pick Expert Consensus Rank (ECR) for PPR - Superflex League",
),
"value_keeper": st.column_config.NumberColumn(
label="Value Keeper",
help="Approx. number of draft rounds of keeper value vs ECR PPR - Superflex League",
),
},
)
def get_keeper_app():
keeper_title = f"{LEAGUE_NAME} Keeper Options"
st.set_page_config(page_title=keeper_title, page_icon=DEFAULT_ICON, layout="wide")
common_page_config()
st.title(keeper_title)
data, teams_list = load_data()
with st.container():
filtered_keeper_dataframe(data, teams_list)
if __name__ == "__main__":
get_keeper_app()
|