コード例 #1
0
ファイル: TeamGenerator.py プロジェクト: nateharner01/MCC
class TeamGenerator:
    def __init__(self, config):
        self.salary_cap = 60000
        self.selection_multiplier = 100 #Multiply EFPPG by 100 so we can encapsulate remainder in integer array
        self.config = config
        self.team_selector = TeamSelector(config['TeamSelector'])

    def select_top_team(self, player_stats, player_costs, date):
        print 'Selecting top team for date: ' + str(date)
        start_time = time.time()
        players = self._merge_player_stats_and_costs(player_stats, player_costs, date)
        players = self._filter_players(players)

        possible_teams = self._all_possible_teams(players)
        possible_teams = self._filter_on_cap_exceeded_np(possible_teams)
        top_team = self.team_selector.select_team(possible_teams, player_stats, date)
        end_time = time.time()
        print 'Simulation finished with runtime: ' + str(end_time - start_time)

        expected_points = self._expected_points(top_team)
        self._print_top_teams(top_team, players)
        return {'team': top_team, 'expected': expected_points}

    def _merge_player_stats_and_costs(self, player_stats, player_costs, date):
        player_stats['Name'] = player_stats['PLAYER']
        player_stats = player_stats[player_stats['Date'] < date]
        player_stats = player_stats.sort_values('Date')
        player_stats = player_stats.groupby('Player_ID').tail(1)

        player_costs['Name'] = player_costs['First Name'] + ' ' + player_costs['Last Name']
        player_costs['FPPG_Per_Dollar'] = player_costs['FPPG'] / player_costs['Salary'] * 10000

        player_stats_costs = pd.merge(player_costs, player_stats, on='Name', how='outer')
        # Eliminate players with no E_FPPG
        player_stats_costs = player_stats_costs[np.isfinite(player_stats_costs[self.config['Selection_Field']])]

        player_stats_costs['EFPPG_Per_Dollar'] = player_stats_costs['E_FPPG'] / player_stats_costs['Salary'] *10000

        player_stats_costs = player_stats_costs[np.isfinite(player_stats_costs['EFPPG_Per_Dollar'])]
        print 'Unfiltered Player Count : {0}'.format(len(player_costs))

        return player_stats_costs


    def _filter_players(self, players):
        filtered_players = players[players['Injury Indicator'].isnull()]
        filtered_players = filtered_players.sort_values(self.config['Filter_Field'], ascending=False)
        filtered_players = filtered_players.iloc[0:self.config['Player_Count']]

        print 'Filtered Player Count : {0}'.format(len(filtered_players))
        return filtered_players

    def _filter_team_fppg_per_dollar_pctile(self, input_teams, pctile):
        fppg_totals = np.sum(input_teams[:,:,2], axis=1) / (1.0 * np.sum(input_teams[:,:,3], axis=1))
        new_len = int(input_teams.shape[0]*pctile)
        index = np.argsort(fppg_totals)
        return input_teams[index[new_len:], :, :]

    def _filter_on_cap_exceeded_np(self, input_teams):
        mask = np.sum(input_teams[:, :, 3], axis=1) <= self.salary_cap
        return input_teams[mask, :, :]

    def _cartesian(self, x, y):
        return np.concatenate((np.tile(x, (len(y), 1, 1)), np.repeat(y, len(x), axis=0)), axis=1)

    def _player_array_from_position(self, players, position):
        mask = players['Position'] == position
        player_data = [players['Player_ID'][mask], players['TeamID'][mask], players[self.config['Selection_Field']][mask] * self.selection_multiplier, players['Salary'][mask]]
        player_data = np.asarray(player_data).astype(np.int32).T.tolist()
        return player_data

    def _possible_teams_from_combos(self, first_position_combos, second_position_combos, filter_size_bytes):
        first_position_combos = self._filter_team_fppg_per_dollar_pctile(first_position_combos, filter_size_bytes)
        return self._cartesian(first_position_combos, second_position_combos)

    def _position_combos(self, players, position, num):
        position_players = self._player_array_from_position(players, position)
        if num == 1:
            return np.expand_dims(np.array(position_players), 1).astype(np.int32)
        else:
            return np.array(list(combinations(position_players, 2))).astype(np.int32)

    def _all_possible_teams(self, players):
        pg_combos = self._position_combos(players, 'PG', 2)
        sg_combos = self._position_combos(players, 'SG', 2)
        pf_combos = self._position_combos(players, 'PF', 2)
        sf_combos = self._position_combos(players, 'SF', 2)
        c_combos = self._position_combos(players, 'C', 1)
        possible_teams = self._possible_teams_from_combos(pg_combos, sg_combos, self.config['Team_Size_Bytes_1'])
        possible_teams = self._possible_teams_from_combos(possible_teams, pf_combos, self.config['Team_Size_Bytes_1'])
        possible_teams = self._possible_teams_from_combos(possible_teams, sf_combos, self.config['Team_Size_Bytes_2'])
        return self._possible_teams_from_combos(possible_teams, c_combos, self.config['Team_Size_Bytes_3'])

    def _expected_points(self, team):
        return np.sum(team[:,:,2], axis=1) / (1.0 * self.selection_multiplier)

    def _print_top_teams(self, top_teams, players):
        fppg_totals = np.sum(top_teams[:,:,2], axis=1) / (1.0 * self.selection_multiplier)
        salary_totals = np.sum(top_teams[:, :, 3], axis=1)

        for i, team in enumerate(top_teams):
            print "Team Expectation: " + str(fppg_totals[i])
            print "Salary Utilized: " + str(salary_totals[i])
            for player_id in team[:,0]:
                if player_id > 0:
                    player = players['Name'][players['Player_ID'] == player_id].iloc[0]
                    team = players['Team'][players['Player_ID'] == player_id].iloc[0]
                    position = players['Position'][players['Player_ID'] == player_id].iloc[0]
                    points = players[self.config['Selection_Field']][players['Player_ID']==player_id].iloc[0]
                    salary = players['Salary'][players['Player_ID']==player_id].iloc[0]
                    print player + ' ' + team + ' ' + position + ' ' + str(points) + ' $' + str(salary)
            print ''