<jupyter_start><jupyter_text>Read in rankings<jupyter_code># year_rankFrame_dict = {} # {year:DataFrame}
# for f in os.listdir(working_directory + '/rankings_ffc_standard'):
#     json_path = working_directory + '/rankings_ffc_standard/' + f
#     ranks = pd.read_json(json_path, typ='series')
#     adp_list = [x['adp'] for x in ranks['players']]
#     name_list = [x['name'] for x in ranks['players']]
#     position_list = [x['position'] for x in ranks['players']]
    
#     year = f.split('_')[-1].replace('.json','')
    
#     rankFrame = pd.DataFrame({'ADP':adp_list, 'Position':position_list, 'Name':name_list})
#     year_rankFrame_dict[year] = rankFrame
    

year_rankFrame_dict = {} # {year:DataFrame}
for f in os.listdir(working_directory + '/rankings_mfl_standard'):
    csv_path = working_directory + '/rankings_mfl_standard/' + f
    rankFrame = pd.read_csv(csv_path, sep=',')
    rankFrame['POSITION'] = [x.split(' ')[-1].replace('*','') for x in rankFrame['PLAYER'].values]
    rankFrame['NAME'] = [' '.join(x.split(', ')[1].split(' ')[:-2]) + ' ' + x.split(', ')[0].replace(',','') for x in rankFrame['PLAYER'].values]
    
    rankFrame = rankFrame[rankFrame['POSITION'].isin(['Def', 'PK', 'QB', 'RB', 'TE', 'WR'])]
    rankFrame['ADP SCORE'] = rankFrame['AVG. PICK'].max() - rankFrame['AVG. PICK'].values
    year = f.split('_')[-1].replace('.csv','')
    
    year_rankFrame_dict[year] = rankFrame<jupyter_output><empty_output><jupyter_text>Read in season results<jupyter_code>year_playerScore_dict = {} # {year:DataFrame}
for f in os.listdir(working_directory + '/scoring_standard'):
    score_path = working_directory + '/scoring_standard/' + f
    scoreFrame = pd.read_csv(score_path, sep=',')
    year = f.split('_')[-1].replace('.csv','')
    current_dict = dict(zip(scoreFrame['Player'].values, scoreFrame['Points'].values))
    year_playerScore_dict[year] = current_dict
    

current_dict<jupyter_output><empty_output><jupyter_text>Create Players<jupyter_code>position_index_dict = dict(zip(sorted(rankFrame['POSITION'].unique()), 
                               range(len(rankFrame['POSITION'].unique()))))
index_position_dict = dict(zip(range(len(rankFrame['POSITION'].unique())),
                                sorted(rankFrame['POSITION'].unique()), 
                               ))
position_index_dict # gives the position and the corresponding index
index_position_dict # gives the index and the corresponding index
def create_new_players(num_players, num_rounds):
    '''
    Randomly create simulated fantasy players
    inputs: number of players and rounds
    outputs: list of fantasy players
    '''
    num_positions = 6 # number of positions
    player_list = []
    for player_number in range(num_players):
        new_player = []
        for round_number in range(num_rounds):
            weights = np.random.random(num_positions) # initialize random weights
            normed_weights = weights/np.sum(weights) # normalize so weights sum to 1
            new_player.append(normed_weights)
    
        player_list.append((new_player))
    return np.array(player_list)
len(rankFrame['POSITION'].unique()) # number of positions
fantasy_players = create_new_players(12, 10)
fantasy_players.shape # first index gives the player
                      # second index gives the round
                      # third index gives the position 

fantasy_players[0,0,0] #gives the importance for player 1 in the first round for a defense 
fantasy_players[0,0,1] #gives the importance for player 1 in the first round for a place kicker (PK)
fantasy_players[8,3,2] #gives the importance for player 9 in the fourth round for a QB
fantasy_players.shape<jupyter_output><empty_output><jupyter_text>Run Simulation<jupyter_code>rankFrame = year_rankFrame_dict['2017']

playerScoreDict = year_playerScore_dict['2017']
rankFrame.shape
len(playerScoreDict)
score_players = set (playerScoreDict.keys())
rank_players = set(rankFrame['NAME'].values)
len(score_players - rank_players)
len(rank_players-score_players)
rankFrame.head()
playerScoreDict
fantasy_players.shape
def simulate_draft(rankFrame, fantasy_players, num_rounds):
    '''
    Simulates a draft and returns a list of rosters for each fantasy player
    inputs: rankFrame - DataFrame containing ranks of players
            fantasy_players - list of fantasy players with different strategies
            num_rounds - number of rounds in the draft
    output: team_rosters - roster selected by each fantasy player
    '''
    team_rosters = [[] for x in range(fantasy_players.shape[0])]
        
    drafted_players = set()
    flip = False
    for draft_round in range(num_rounds):
        for player_index in range(fantasy_players.shape[0]):
            if flip:
                player = fantasy_players.shape[0] - player_index - 1
            else:
                player = player_index
            
#             print(draft_round, player)
            # retrieve strategy
            round_strategy = fantasy_players[player,draft_round, :]
            player_score_tuples = []
            # calculate player ranks
            for index, row in rankFrame[~rankFrame['NAME'].isin(drafted_players)].iterrows(): 
                position = row['POSITION']
                position_weight = round_strategy[position_index_dict[position]]
                weighted_player_score = position_weight * float(row['ADP SCORE'])
                player_score_tuples.append((row['NAME'], weighted_player_score, position))
            
            # draft player
            player_score_tuples.sort(key = lambda x: x[1], reverse=True)
            drafted_player = (player_score_tuples[0][0], player_score_tuples[0][2])
            
            team_rosters[player].append(drafted_player)
            drafted_players.add(drafted_player[0])
        if flip == False:
            flip = True
        else:
            flip = False
    return team_rosters
start = time.time()
rosters = simulate_draft(rankFrame, fantasy_players, 10)
print('time to draft', time.time() - start)
#  check rosters don't overlap
for i in range(len(rosters)-1):
    for j in range(i+1, len(rosters)):
        team1 = rosters[i]
        team2 = rosters[j]
        print(i, j, len(set(team1).intersection(set(team2))))
scoreFrame.head()
playerScoreDict
def score_roster(playerScoreDict, fantasy_rosters):
    '''
    returns a list of performances for each fantasy player's team and lineups for each team
    '''
    fantasy_team_performances = []
    fantasy_lineups = []
    for roster in fantasy_rosters:  
        lineup = []
        roster_with_scores = [(x[0], x[1], playerScoreDict[x[0]]) if x[0] in playerScoreDict else (x[0], x[1], 0) for x in roster]
        roster_with_scores.sort(key = lambda x:x[2], reverse=True)
        
        # fill regular roster
        for pos in ['QB', 'WR', 'WR', 'RB', 'RB', 'PK', 'DEF']:
            selected_player = ('No Selection', pos, 0)
            player_selected = False
            for player in roster_with_scores:
                if player[1] == pos:
                    selected_player = player
                    player_selected = True
                    break
            lineup.append(selected_player)
            if player_selected:
                roster_with_scores.remove(selected_player)
                
        # fill flex
        selected_player = ('No Selection', pos, 0)
        for player in roster_with_scores:
            if player[1] in ['WR', 'RB', 'TE']:
                selected_player = player
                player_selected = True
                break
        lineup.append(selected_player)
        
        performance = np.sum(x[2] for x in lineup)
        
        fantasy_lineups.append(lineup)
        fantasy_team_performances.append(performance)
        
    return fantasy_team_performances, fantasy_lineups
   

performances, lineups= score_roster(playerScoreDict, copy.deepcopy(rosters))
performances
lineups
def update_players(fantasy_players, fantasy_team_performances, num_players, mutation_rate=1.0, num_survivors = 4):
    '''
    Given a list of fantasy players with different strategies and the performance of each strategy,
    creates a new generation of fantasy players
    '''
    num_positions = 6 # number of positions
    
    performance_tuple_list = list (zip(fantasy_team_performances, fantasy_players))
    performance_tuple_list.sort(key = lambda x:x[0], reverse=True)
    
    playoff_players = np.array([x[1] for x in performance_tuple_list[:num_survivors]]) # get top players
    
    new_players = []
    # recombination
    for player in range(num_players):
        new_player = []
        parent1 = np.random.randint(playoff_players.shape[0])
        parent2 = np.random.randint(playoff_players.shape[0])
        for draft_round in range(fantasy_players.shape[1]):
            mean_chromosome = (playoff_players[parent1,draft_round,:] + playoff_players[parent2,draft_round,:])/2
            
            weights = mutation_rate * np.random.random(num_positions) # initialize random weights
            mutated_chromosome = mean_chromosome +  weights
            normed_chromosome = mutated_chromosome/np.sum(mutated_chromosome) # normalize so weights sum to 1
            
            new_player.append(normed_chromosome)

        new_players.append(new_player)
    
    return np.array(new_players)<jupyter_output><empty_output><jupyter_text>Run Basic Simulation<jupyter_code>num_simulations = 900
draft_rounds = 15
num_players = 12

best_strategy_list = []
mean_performance_list = []
best_performance_list = []
rankFrame = year_rankFrame_dict['2017']
playerScoreDict = year_playerScore_dict['2017']
iteration_players = create_new_players(num_players, draft_rounds)
for iteration in range(num_simulations):
    start = time.time()
    iteration_rosters = simulate_draft(rankFrame, iteration_players, num_rounds=draft_rounds)
    iteration_performances, iteration_lineups = score_roster(playerScoreDict, copy.deepcopy(iteration_rosters))
    
    iteration_players = update_players(iteration_players, 
                                       iteration_performances, 
                                       num_players, 
                                       mutation_rate=0.5, 
                                       num_survivors = 6)
    sorted_players = np.array([x [1] for x in sorted(list(zip(iteration_performances, iteration_players)), 
                                        key = lambda x:x[0], reverse = True)])
    
    mean_performance_list.append(np.mean(iteration_performances))
    best_performance_list.append(np.max(iteration_performances))
    best_strategy_list.append(sorted_players[0])
    
    print(iteration, 
          np.round(time.time() - start, 2),
          sorted(list(zip(iteration_performances, range(len(iteration_performances)))), key = lambda x:x[0]), 
          np.mean(iteration_performances), 
          np.max(iteration_performances) - np.min(iteration_performances))
    

plt.plot(best_performance_list, label = 'best')
plt.plot(mean_performance_list, label = 'avg')
plt.legend()
iteration_players.shape
position_index_dict
sorted_players = np.array([x [1] for x in sorted(list(zip(iteration_performances, iteration_players)), 
                                        key = lambda x:x[0], reverse = True)])
for p in sorted_players:
    
    print([index_position_dict[x] for x in p.argmax(axis=1)])<jupyter_output>['WR', 'PK', 'RB', 'RB', 'PK', 'PK', 'RB', 'QB', 'QB', 'Def', 'WR', 'RB', 'TE', 'TE', 'QB']
['QB', 'RB', 'Def', 'QB', 'WR', 'QB', 'PK', 'TE', 'WR', 'PK', 'WR', 'TE', 'Def', 'PK', 'TE']
['QB', 'TE', 'PK', 'PK', 'PK', 'Def', 'TE', 'Def', 'TE', 'TE', 'RB', 'TE', 'PK', 'QB', 'PK']
['TE', 'PK', 'RB', 'QB', 'Def', 'PK', 'WR', 'PK', 'QB', 'PK', 'RB', 'RB', 'PK', 'TE', 'PK']
['QB', 'WR', 'Def', 'RB', 'PK', 'TE', 'QB', 'Def', 'WR', 'Def', 'TE', 'WR', 'QB', 'Def', 'WR']
['Def', 'RB', 'Def', 'Def', 'TE', 'QB', 'RB', 'Def', 'RB', 'QB', 'Def', 'WR', 'PK', 'WR', 'WR']
['QB', 'QB', 'QB', 'PK', 'QB', 'PK', 'TE', 'RB', 'WR', 'RB', 'PK', 'PK', 'QB', 'RB', 'RB']
['Def', 'QB', 'QB', 'RB', 'TE', 'PK', 'WR', 'WR', 'WR', 'Def', 'Def', 'Def', 'RB', 'Def', 'PK']
['QB', 'RB', 'PK', 'Def', 'TE', 'QB', 'QB', 'TE', 'PK', 'WR', 'QB', 'PK', 'QB', 'TE', 'WR']
['QB', 'WR', 'Def', 'RB', 'PK', 'TE', 'TE', 'Def', 'WR', 'WR', 'WR', 'WR', 'RB', 'PK', 'PK']
['TE', 'PK', 'Def', 'PK', 'WR', 'PK', 'Def', 'PK', 'RB', 'RB', 'PK'[...]
{'fraction_non_alphanumeric': 0.1395685769478429, 'fraction_numerical': 0.008451384417256923, 'mean_word_length': 3.1778749159381303, 'pattern_counts': {'":': 0, '<': 20, '<?xml version=': 0, '>': 20, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 8, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '5', 'dir': 'jupyter-structured-clean-dedup', 'id': '125671', 'license': 'MIT', 'n_tokens_mistral': 4088, 'n_tokens_neox': 3939, 'n_words': 895, 'path': 'Genetic Algorithm Fantasy Draft.ipynb', 'repo_name': 'jenhantao/fantasy_football_genetic_algorithm_draft', 'size': '12424'}