James McCool
commited on
Commit
·
eb3c53f
1
Parent(s):
3a9fcee
Refactor player filtering and portfolio distribution logic in distribute_preset.py to streamline the process of removing high-exposure players. This update enhances the accuracy of lineup generation by ensuring that the final portfolio meets the lineup target while maintaining performance metrics, and improves the handling of player selection based on similarity scores.
Browse files- global_func/distribute_preset.py +64 -72
global_func/distribute_preset.py
CHANGED
@@ -5,84 +5,76 @@ def distribute_preset(portfolio: pd.DataFrame, lineup_target: int, exclude_cols:
|
|
5 |
|
6 |
excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', 'Similarity Score']
|
7 |
player_columns = [col for col in portfolio.columns if col not in excluded_cols]
|
8 |
-
|
9 |
-
|
10 |
-
|
11 |
-
|
12 |
-
|
13 |
-
concat_portfolio = pd.DataFrame(columns=portfolio.columns)
|
14 |
-
|
15 |
-
# Start with the original portfolio, removing players from player_remove_list
|
16 |
working_portfolio = portfolio.copy()
|
17 |
-
|
18 |
-
|
19 |
-
|
20 |
-
remove_mask = working_portfolio[player_columns].apply(
|
21 |
-
lambda row: not any(player in list(row) for player in player_remove_list), axis=1
|
22 |
-
)
|
23 |
-
working_portfolio = working_portfolio[remove_mask]
|
24 |
-
|
25 |
-
if len(working_portfolio) == 0:
|
26 |
-
# If no data left after removing players, return what we have
|
27 |
-
return concat_portfolio.sort_values(by='median', ascending=False)
|
28 |
-
|
29 |
-
# Apply similarity score filtering by team
|
30 |
-
for team in working_portfolio['Stack'].unique():
|
31 |
-
rows_to_drop = []
|
32 |
-
team_portfolio = working_portfolio[working_portfolio['Stack'] == team].sort_values(by='median', ascending=False)
|
33 |
-
team_portfolio = team_portfolio.reset_index(drop=True)
|
34 |
-
|
35 |
-
if len(team_portfolio) == 0:
|
36 |
-
continue
|
37 |
-
|
38 |
-
curr_own_type_max = team_portfolio.loc[0, 'Similarity Score'] + (slack_var / 20 * team_portfolio.loc[0, 'Similarity Score'])
|
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 |
-
'Player': player,
|
69 |
-
'Lineup Count': player_mask.sum(),
|
70 |
-
'Exposure': player_mask.sum() / len(concat_portfolio)
|
71 |
-
})
|
72 |
|
73 |
-
|
74 |
-
|
75 |
-
|
76 |
-
# Find players with exposure > 0.60
|
77 |
-
high_exposure_players = player_summary[player_summary['Exposure'] > 0.60]['Player'].tolist()
|
78 |
-
|
79 |
-
# Add new high-exposure players to the remove list
|
80 |
-
player_remove_list.extend(high_exposure_players)
|
81 |
-
|
82 |
-
# If no new players to remove and we have enough lineups, we're done
|
83 |
-
if len(high_exposure_players) == 0 and len(concat_portfolio) >= lineup_target:
|
84 |
-
break
|
85 |
-
|
86 |
-
x += 1
|
87 |
|
88 |
return concat_portfolio.sort_values(by='median', ascending=False)
|
|
|
5 |
|
6 |
excluded_cols = ['salary', 'median', 'Own', 'Finish_percentile', 'Dupes', 'Stack', 'Size', 'Win%', 'Lineup Edge', 'Weighted Own', 'Geomean', 'Similarity Score']
|
7 |
player_columns = [col for col in portfolio.columns if col not in excluded_cols]
|
8 |
+
for slack_var in range(1, 20):
|
9 |
+
init_portfolio = pd.DataFrame(columns=portfolio.columns)
|
10 |
+
|
11 |
+
for team in portfolio['Stack'].unique():
|
12 |
+
rows_to_drop = []
|
|
|
|
|
|
|
13 |
working_portfolio = portfolio.copy()
|
14 |
+
working_portfolio = working_portfolio[working_portfolio['Stack'] == team].sort_values(by='median', ascending = False)
|
15 |
+
working_portfolio = working_portfolio.reset_index(drop=True)
|
16 |
+
curr_own_type_max = working_portfolio.loc[0, 'Similarity Score'] + (slack_var / 20 * working_portfolio.loc[0, 'Similarity Score'])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
+
for i in range(1, len(working_portfolio)):
|
19 |
+
if working_portfolio.loc[i, 'Similarity Score'] > curr_own_type_max:
|
20 |
+
rows_to_drop.append(i)
|
21 |
+
else:
|
22 |
+
curr_own_type_max = working_portfolio.loc[i, 'Similarity Score'] + (slack_var / 20 * working_portfolio.loc[i, 'Similarity Score'])
|
23 |
+
|
24 |
+
working_portfolio = working_portfolio.drop(rows_to_drop).reset_index(drop=True)
|
25 |
+
init_portfolio = pd.concat([init_portfolio, working_portfolio])
|
26 |
|
27 |
+
if len(init_portfolio) >= lineup_target:
|
28 |
+
init_portfolio.sort_values(by='median', ascending=True).head(lineup_target)
|
29 |
+
|
30 |
+
player_list = set()
|
31 |
+
player_stats = []
|
32 |
+
for cols in init_portfolio.columns:
|
33 |
+
if cols not in excluded_cols:
|
34 |
+
player_list.update(init_portfolio[cols].unique())
|
35 |
+
|
36 |
+
for player in player_list:
|
37 |
+
# Select only the columns that are NOT in excluded_cols
|
38 |
+
player_cols = [col for col in init_portfolio.columns if col not in excluded_cols]
|
39 |
+
player_mask = init_portfolio[player_cols].apply(
|
40 |
+
lambda row: player in list(row), axis=1
|
41 |
+
)
|
42 |
|
43 |
+
if player_mask.any():
|
44 |
+
player_stats.append({
|
45 |
+
'Player': player,
|
46 |
+
'Lineup Count': player_mask.sum(),
|
47 |
+
'Exposure': player_mask.sum() / len(init_portfolio)
|
48 |
+
})
|
49 |
+
|
50 |
+
player_summary = pd.DataFrame(player_stats)
|
51 |
+
print(player_summary.sort_values('Lineup Count', ascending=False).head(10))
|
52 |
+
player_remove_list = player_summary.sort_values('Lineup Count', ascending=False).head(5)['Player'].tolist()
|
53 |
+
|
54 |
+
for slack_var in range(1, 20):
|
55 |
+
concat_portfolio = pd.DataFrame(columns=portfolio.columns)
|
56 |
+
|
57 |
+
for player_out in player_remove_list:
|
58 |
+
rows_to_drop = []
|
59 |
+
working_portfolio = portfolio.copy()
|
60 |
+
remove_mask = working_portfolio[player_columns].apply(
|
61 |
+
lambda row: player_out not in list(row), axis=1
|
62 |
)
|
63 |
+
working_portfolio = working_portfolio[remove_mask]
|
64 |
+
print(working_portfolio.head(10))
|
65 |
+
working_portfolio = working_portfolio.sort_values(by='median', ascending=False).reset_index(drop=True)
|
66 |
+
curr_own_type_max = working_portfolio.loc[0, 'Similarity Score'] + (slack_var / 20 * working_portfolio.loc[0, 'Similarity Score'])
|
67 |
+
|
68 |
+
for i in range(1, len(working_portfolio)):
|
69 |
+
if working_portfolio.loc[i, 'Similarity Score'] > curr_own_type_max:
|
70 |
+
rows_to_drop.append(i)
|
71 |
+
else:
|
72 |
+
curr_own_type_max = working_portfolio.loc[i, 'Similarity Score'] + (slack_var / 20 * working_portfolio.loc[i, 'Similarity Score'])
|
73 |
|
74 |
+
working_portfolio = working_portfolio.drop(rows_to_drop).reset_index(drop=True)
|
75 |
+
concat_portfolio = pd.concat([concat_portfolio, working_portfolio.head(math.ceil(lineup_target / 5))])
|
|
|
|
|
|
|
|
|
76 |
|
77 |
+
if len(concat_portfolio) >= lineup_target:
|
78 |
+
return concat_portfolio.sort_values(by='median', ascending=False).head(lineup_target)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
79 |
|
80 |
return concat_portfolio.sort_values(by='median', ascending=False)
|