|
import random |
|
import numpy as np |
|
import math |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def check_nba_position_eligibility(column_name, player_positions): |
|
if 'PG' in column_name: |
|
return 'PG' in player_positions |
|
elif 'SG' in column_name: |
|
return 'SG' in player_positions |
|
elif 'SF' in column_name: |
|
return 'SF' in player_positions |
|
elif 'PF' in column_name: |
|
return 'PF' in player_positions |
|
elif 'C' in column_name: |
|
return 'C' in player_positions |
|
elif 'G' in column_name: |
|
return any(pos in ['PG', 'SG'] for pos in player_positions) |
|
elif 'F' in column_name: |
|
return any(pos in ['SF', 'PF'] for pos in player_positions) |
|
elif 'UTIL' in column_name: |
|
return True |
|
return False |
|
|
|
def check_lol_position_eligibility(column_name, player_positions): |
|
if 'TOP' in column_name: |
|
return 'TOP' in player_positions |
|
elif 'JNG' in column_name: |
|
return 'JNG' in player_positions |
|
elif 'MID' in column_name: |
|
return 'MID' in player_positions |
|
elif 'ADC' in column_name: |
|
return 'ADC' in player_positions |
|
elif 'SUP' in column_name: |
|
return 'SUP' in player_positions |
|
elif 'Team' in column_name: |
|
return 'Team' in player_positions |
|
elif 'CPT' in column_name: |
|
return any(pos in ['TOP', 'JNG', 'MID', 'ADC', 'SUP'] for pos in player_positions) |
|
return False |
|
|
|
def check_mlb_position_eligibility(column_name, player_positions): |
|
if any(pos in column_name for pos in ['P', 'SP', 'RP']): |
|
return any(pos in ['P', 'SP', 'RP'] for pos in player_positions) |
|
elif 'C' in column_name: |
|
return 'C' in player_positions |
|
elif '1B' in column_name: |
|
return '1B' in player_positions |
|
elif '2B' in column_name: |
|
return '2B' in player_positions |
|
elif '3B' in column_name: |
|
return '3B' in player_positions |
|
elif 'SS' in column_name: |
|
return 'SS' in player_positions |
|
elif 'OF' in column_name: |
|
return 'OF' in player_positions |
|
return False |
|
|
|
def check_nfl_position_eligibility(column_name, player_positions): |
|
if 'QB' in column_name: |
|
return 'QB' in player_positions |
|
elif 'RB' in column_name: |
|
return 'RB' in player_positions |
|
elif 'WR' in column_name: |
|
return 'WR' in player_positions |
|
elif 'TE' in column_name: |
|
return 'TE' in player_positions |
|
elif 'DST' in column_name: |
|
return 'DST' in player_positions |
|
elif 'FLEX' in column_name: |
|
return any(pos in ['RB', 'WR', 'TE'] for pos in player_positions) |
|
elif 'UTIL' in column_name: |
|
return any(pos in ['RB', 'WR', 'TE'] for pos in player_positions) |
|
return False |
|
|
|
def check_golf_position_eligibility(column_name, player_positions): |
|
if 'FLEX' in column_name: |
|
return any(pos in ['G'] for pos in player_positions) |
|
return True |
|
|
|
def check_tennis_position_eligibility(column_name, player_positions): |
|
if 'FLEX' in column_name: |
|
return any(pos in ['T'] for pos in player_positions) |
|
return True |
|
|
|
def check_mma_position_eligibility(column_name, player_positions): |
|
if 'FLEX' in column_name: |
|
return any(pos in ['F'] for pos in player_positions) |
|
return True |
|
|
|
def check_nascar_position_eligibility(column_name, player_positions): |
|
if 'FLEX' in column_name: |
|
return any(pos in ['D'] for pos in player_positions) |
|
return True |
|
|
|
def check_ncaaf_position_eligibility(column_name, player_positions): |
|
if 'QB' in column_name: |
|
return 'QB' in player_positions |
|
elif 'RB' in column_name: |
|
return 'RB' in player_positions |
|
elif 'WR' in column_name: |
|
return 'WR' in player_positions |
|
elif 'FLEX' in column_name: |
|
return any(pos in ['RB', 'WR'] for pos in player_positions) |
|
elif 'SFLEX' in column_name: |
|
return any(pos in ['RB', 'WR', 'QB'] for pos in player_positions) |
|
return False |
|
|
|
def check_nhl_position_eligibility(column_name, player_positions): |
|
if 'C' in column_name: |
|
return 'C' in player_positions |
|
elif 'W' in column_name: |
|
return 'W' in player_positions |
|
elif 'D' in column_name: |
|
return 'D' in player_positions |
|
elif 'G' in column_name: |
|
return 'G' in player_positions |
|
elif 'FLEX' in column_name: |
|
return any(pos in ['C', 'W', 'D'] for pos in player_positions) |
|
elif 'UTIL' in column_name: |
|
return any(pos in ['C', 'W', 'D'] for pos in player_positions) |
|
return False |
|
|
|
def check_position_eligibility(sport, column_name, player_positions): |
|
if sport == 'NBA': |
|
return check_nba_position_eligibility(column_name, player_positions) |
|
elif sport == 'MLB': |
|
return check_mlb_position_eligibility(column_name, player_positions) |
|
elif sport == 'NFL': |
|
return check_nfl_position_eligibility(column_name, player_positions) |
|
elif sport == 'NHL': |
|
return check_nhl_position_eligibility(column_name, player_positions) |
|
elif sport == 'MMA': |
|
return check_mma_position_eligibility(column_name, player_positions) |
|
elif sport == 'GOLF': |
|
return check_golf_position_eligibility(column_name, player_positions) |
|
elif sport == 'TENNIS': |
|
return check_tennis_position_eligibility(column_name, player_positions) |
|
elif sport == 'LOL': |
|
return check_lol_position_eligibility(column_name, player_positions) |
|
else: |
|
|
|
return column_name in player_positions |
|
|
|
def exposure_spread(working_frame, exposure_player, exposure_target, ignore_stacks, remove_teams, specific_replacements, specific_columns, projections_df, sport_var, type_var, salary_max, stacking_sports): |
|
comparable_players = projections_df[projections_df['player_names'] == exposure_player] |
|
|
|
comparable_players = comparable_players.reset_index(drop=True) |
|
comp_salary_high = comparable_players['salary'][0] |
|
if type_var == 'Showdown': |
|
comp_salary_low = comparable_players['salary'][0] - 1000 |
|
else: |
|
comp_salary_low = comparable_players['salary'][0] - 500 |
|
comp_projection_high = comparable_players['median'][0] |
|
if type_var == 'Showdown': |
|
comp_projection_low = comparable_players['median'][0] - (comparable_players['median'][0] * .5) |
|
else: |
|
comp_projection_low = comparable_players['median'][0] - (comparable_players['median'][0] * .75) |
|
|
|
|
|
comp_player_position = comparable_players['position'].tolist() |
|
comp_team = comparable_players['team'].tolist() |
|
try: |
|
comp_player_position = [pos.split('/') for pos in comp_player_position] |
|
comp_player_position = [item for sublist in comp_player_position for item in sublist] |
|
comp_player_position = list(set(comp_player_position)) |
|
except: |
|
comp_player_position = comparable_players['position'].tolist() |
|
|
|
def has_position_overlap(player_positions, target_positions): |
|
player_pos_list = player_positions.split('/') |
|
return any(pos in target_positions for pos in player_pos_list) |
|
|
|
|
|
if specific_columns != []: |
|
player_mask = working_frame[specific_columns].apply( |
|
lambda row: exposure_player in list(row), axis=1 |
|
) |
|
else: |
|
player_mask = working_frame[working_frame.columns].apply( |
|
lambda row: exposure_player in list(row), axis=1 |
|
) |
|
|
|
if specific_columns != []: |
|
replace_mask = working_frame[specific_columns].apply( |
|
lambda row: exposure_player not in list(row), axis=1 |
|
) |
|
else: |
|
replace_mask = working_frame[working_frame.columns].apply( |
|
lambda row: exposure_player not in list(row), axis=1 |
|
) |
|
|
|
player_exposure = player_mask.sum() / len(working_frame) |
|
replace_exposure = replace_mask.sum() / len(working_frame) |
|
|
|
|
|
if exposure_target == 0: |
|
lineups_to_remove = (player_exposure * len(working_frame)) |
|
else: |
|
lineups_to_remove = ((player_exposure - exposure_target) * len(working_frame)) * 1.01 |
|
lineups_to_add = ((exposure_target - player_exposure) * (len(working_frame) - (player_exposure * len(working_frame)))) * 1.10 |
|
|
|
|
|
player_rows = working_frame[player_mask] |
|
replace_rows = working_frame[replace_mask] |
|
if ignore_stacks != []: |
|
player_rows = player_rows[~player_rows['Stack'].isin(ignore_stacks)] |
|
replace_rows = replace_rows[~replace_rows['Stack'].isin(ignore_stacks)] |
|
|
|
change_counter = 0 |
|
|
|
random_row_indices_insert = list(player_rows.index) |
|
random_row_indices_replace = list(replace_rows.index) |
|
random.shuffle(random_row_indices_insert) |
|
random.shuffle(random_row_indices_replace) |
|
|
|
|
|
|
|
|
|
|
|
|
|
if lineups_to_remove > 0: |
|
for row in random_row_indices_insert: |
|
if change_counter < math.ceil(lineups_to_remove): |
|
if specific_replacements != []: |
|
comparable_players = projections_df[(projections_df['player_names'].isin(specific_replacements)) & |
|
(projections_df['salary'] <= comp_salary_high + (salary_max - working_frame['salary'][row])) |
|
] |
|
else: |
|
comparable_players = projections_df[ |
|
(projections_df['salary'] >= comp_salary_low) & |
|
(projections_df['salary'] <= comp_salary_high + (salary_max - working_frame['salary'][row])) & |
|
(projections_df['median'] >= comp_projection_low) & |
|
(projections_df['position'].apply(lambda x: has_position_overlap(x, comp_player_position))) |
|
] |
|
|
|
if exposure_target == 0: |
|
comparable_players = comparable_players[comparable_players['player_names'] != exposure_player] |
|
|
|
if remove_teams is not None: |
|
remove_mask = comparable_players.apply( |
|
lambda row: not any(team in list(row) for team in remove_teams), axis=1 |
|
) |
|
comparable_players = comparable_players[remove_mask] |
|
|
|
|
|
if specific_columns != []: |
|
current_row_data = working_frame.iloc[row][specific_columns] |
|
else: |
|
current_row_data = working_frame.iloc[row] |
|
|
|
|
|
existing_players = set(current_row_data.values) |
|
try: |
|
comparable_players = comparable_players[~comparable_players['player_names'].isin(existing_players)] |
|
comparable_player_list = comparable_players['player_names'].tolist() |
|
except: |
|
comparable_player_list = [] |
|
|
|
if comparable_player_list: |
|
insert_player = random.choice(comparable_player_list) |
|
|
|
if specific_columns != []: |
|
row_data = working_frame.iloc[row][specific_columns] |
|
working_columns = specific_columns |
|
else: |
|
row_data = working_frame.iloc[row] |
|
working_columns = working_frame.columns |
|
|
|
for col in working_columns: |
|
if row_data[col] == exposure_player: |
|
|
|
replacement_player_positions = projections_df[projections_df['player_names'] == insert_player]['position'].iloc[0].split('/') |
|
|
|
|
|
if type_var == 'Classic': |
|
if check_position_eligibility(sport_var, col, replacement_player_positions): |
|
working_frame.at[row, col] = insert_player |
|
break |
|
else: |
|
working_frame.at[row, col] = insert_player |
|
break |
|
change_counter += 1 |
|
else: |
|
for row in random_row_indices_replace: |
|
if change_counter < math.ceil(lineups_to_add): |
|
if specific_replacements != []: |
|
comparable_players = projections_df[(projections_df['player_names'].isin(specific_replacements)) |
|
] |
|
else: |
|
if type_var == 'Showdown': |
|
comparable_players = projections_df[ |
|
(projections_df['salary'] >= comp_salary_low) & |
|
(projections_df['salary'] <= comp_salary_high + (salary_max - working_frame['salary'][row])) |
|
] |
|
else: |
|
comparable_players = projections_df[ |
|
(projections_df['salary'] >= comp_salary_low) & |
|
(projections_df['salary'] <= comp_salary_high + (salary_max - working_frame['salary'][row])) & |
|
(projections_df['position'].apply(lambda x: has_position_overlap(x, comp_player_position))) |
|
] |
|
if sport_var in stacking_sports: |
|
if working_frame.iloc[row]['Size'] == 5 and comp_team != working_frame.iloc[row]['Stack']: |
|
remove_mask = comparable_players.apply( |
|
lambda player_row: not any(team in list(player_row) for team in [working_frame.iloc[row]['Stack']]), axis=1 |
|
) |
|
comparable_players = comparable_players[remove_mask] |
|
|
|
if remove_teams is not None: |
|
remove_mask = comparable_players.apply( |
|
lambda row: not any(team in list(row) for team in remove_teams), axis=1 |
|
) |
|
comparable_players = comparable_players[remove_mask] |
|
|
|
comparable_players = comparable_players[comparable_players['player_names'] != exposure_player] |
|
|
|
|
|
comparable_player_list = comparable_players['player_names'].tolist() |
|
if comparable_player_list: |
|
|
|
if specific_columns != []: |
|
row_data = working_frame.iloc[row][specific_columns] |
|
working_columns = specific_columns |
|
else: |
|
row_data = working_frame.iloc[row] |
|
working_columns = working_frame.columns |
|
|
|
for col in working_columns: |
|
if row_data[col] in comparable_player_list: |
|
if working_frame.iloc[row]['salary'] - projections_df[projections_df['player_names'] == row_data[col]]['salary'].iloc[0] + projections_df[projections_df['player_names'] == exposure_player]['salary'].iloc[0] <= salary_max: |
|
if type_var == 'Classic': |
|
replacement_player_positions = projections_df[projections_df['player_names'] == row_data[col]]['position'].iloc[0].split('/') |
|
exposure_player_positions = projections_df[projections_df['player_names'] == exposure_player]['position'].iloc[0].split('/') |
|
|
|
|
|
|
|
if check_position_eligibility(sport_var, col, exposure_player_positions): |
|
working_frame.at[row, col] = exposure_player |
|
change_counter += 1 |
|
break |
|
else: |
|
working_frame.at[row, col] = exposure_player |
|
change_counter += 1 |
|
break |
|
else: |
|
continue |
|
return working_frame |
|
|