James McCool commited on
Commit
066fad7
·
1 Parent(s): fca5d51

Refactor exposure_spread function to improve player replacement logic by implementing a while loop for better handling of row selections and ensuring replacements are made only when necessary. This enhances the clarity and efficiency of the code.

Browse files
Files changed (1) hide show
  1. global_func/exposure_spread.py +87 -80
global_func/exposure_spread.py CHANGED
@@ -228,100 +228,107 @@ def exposure_spread(working_frame, exposure_player, exposure_target, comp_salary
228
  # key concept here is if they have a lineups to remove above 0 it means that we are trying to replace them with comparable players
229
  # if the lineups to remove is below zero it means we want to find comparable players and replace them with the exposure player
230
  if lineups_to_remove > 0:
231
- for row in random_row_indices_insert:
232
- if change_counter < math.ceil(lineups_to_remove):
233
- if specific_replacements != []:
234
- comparable_players = projections_df[(projections_df['player_names'].isin(specific_replacements)) &
235
- (projections_df['salary'] <= comp_salary_high + (salary_max - working_frame['salary'][row]))
236
- ]
237
- else:
238
- comparable_players = projections_df[
239
- (projections_df['salary'] >= comp_salary_low) &
240
- (projections_df['salary'] <= comp_salary_high + (salary_max - working_frame['salary'][row])) &
241
- (projections_df['median'] >= comp_projection_low) &
242
- (projections_df['position'].apply(lambda x: has_position_overlap(x, comp_player_position)))
243
- ]
 
 
 
244
 
245
- if exposure_target == 0:
246
- comparable_players = comparable_players[comparable_players['player_names'] != exposure_player]
247
-
248
- if remove_teams is not None:
249
- remove_mask = comparable_players.apply(
250
- lambda row: not any(team in list(row) for team in remove_teams), axis=1
251
- )
252
- comparable_players = comparable_players[remove_mask]
253
 
254
- # Get the current row data to check for existing players
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  if specific_columns != []:
256
- current_row_data = working_frame.iloc[row][specific_columns]
 
257
  else:
258
- current_row_data = working_frame.iloc[row]
 
259
 
260
- # Filter out players that are already present in this row
261
- existing_players = set(current_row_data.values)
262
- try:
263
- comparable_players = comparable_players[~comparable_players['player_names'].isin(existing_players)]
264
- comparable_player_list = comparable_players['player_names'].tolist()
265
- except:
266
- comparable_player_list = []
267
-
268
- if comparable_player_list:
269
- # Find which column contains the exposure_player
270
- if specific_columns != []:
271
- row_data = working_frame.iloc[row][specific_columns]
272
- working_columns = specific_columns
273
- else:
274
- row_data = working_frame.iloc[row]
275
- working_columns = working_frame.columns
276
-
277
- # Track if we successfully made a replacement
278
- replacement_made = False
279
-
280
- # For exposure_target == 0, replace ALL occurrences of exposure_player in this row
281
- if exposure_target == 0:
282
- for col in working_columns:
283
- if row_data[col] == exposure_player:
284
- # Try to find a suitable replacement for this specific column
285
- suitable_replacements = []
286
- for candidate in comparable_player_list:
287
- # Get the replacement player's positions
288
- replacement_player_positions = projections_df[projections_df['player_names'] == candidate]['position'].iloc[0].split('/')
289
-
290
- # Check if the replacement player is eligible for this column
291
- if type_var == 'Classic':
292
- if check_position_eligibility(sport_var, col, replacement_player_positions):
293
- suitable_replacements.append(candidate)
294
- else:
295
- suitable_replacements.append(candidate)
296
-
297
- if suitable_replacements:
298
- insert_player = random.choice(suitable_replacements)
299
- working_frame.at[row, col] = insert_player
300
- replacement_made = True
301
- # Remove this player from the list to avoid duplicates in the same row
302
- comparable_player_list = [p for p in comparable_player_list if p != insert_player]
303
- else:
304
- # Original logic for non-zero exposure targets
305
- for col in working_columns:
306
- if row_data[col] == exposure_player:
307
- insert_player = random.choice(comparable_player_list)
308
  # Get the replacement player's positions
309
- replacement_player_positions = projections_df[projections_df['player_names'] == insert_player]['position'].iloc[0].split('/')
310
 
311
  # Check if the replacement player is eligible for this column
312
  if type_var == 'Classic':
313
  if check_position_eligibility(sport_var, col, replacement_player_positions):
314
- working_frame.at[row, col] = insert_player
315
- replacement_made = True
316
- break
317
  else:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
318
  working_frame.at[row, col] = insert_player
319
  replacement_made = True
320
  break
321
-
322
- # Only increment counter if we actually made a replacement
323
- if replacement_made:
324
- change_counter += 1
 
 
 
 
 
 
 
 
325
  else:
326
  for row in random_row_indices_replace:
327
  if change_counter < math.ceil(lineups_to_add):
 
228
  # key concept here is if they have a lineups to remove above 0 it means that we are trying to replace them with comparable players
229
  # if the lineups to remove is below zero it means we want to find comparable players and replace them with the exposure player
230
  if lineups_to_remove > 0:
231
+ # Keep trying until we've made enough successful replacements
232
+ while change_counter < math.ceil(lineups_to_remove) and random_row_indices_insert:
233
+ # Get the next row to try
234
+ row = random_row_indices_insert.pop(0)
235
+
236
+ if specific_replacements != []:
237
+ comparable_players = projections_df[(projections_df['player_names'].isin(specific_replacements)) &
238
+ (projections_df['salary'] <= comp_salary_high + (salary_max - working_frame['salary'][row]))
239
+ ]
240
+ else:
241
+ comparable_players = projections_df[
242
+ (projections_df['salary'] >= comp_salary_low) &
243
+ (projections_df['salary'] <= comp_salary_high + (salary_max - working_frame['salary'][row])) &
244
+ (projections_df['median'] >= comp_projection_low) &
245
+ (projections_df['position'].apply(lambda x: has_position_overlap(x, comp_player_position)))
246
+ ]
247
 
248
+ if exposure_target == 0:
249
+ comparable_players = comparable_players[comparable_players['player_names'] != exposure_player]
250
+
251
+ if remove_teams is not None:
252
+ remove_mask = comparable_players.apply(
253
+ lambda row: not any(team in list(row) for team in remove_teams), axis=1
254
+ )
255
+ comparable_players = comparable_players[remove_mask]
256
 
257
+ # Get the current row data to check for existing players
258
+ if specific_columns != []:
259
+ current_row_data = working_frame.iloc[row][specific_columns]
260
+ else:
261
+ current_row_data = working_frame.iloc[row]
262
+
263
+ # Filter out players that are already present in this row
264
+ existing_players = set(current_row_data.values)
265
+ try:
266
+ comparable_players = comparable_players[~comparable_players['player_names'].isin(existing_players)]
267
+ comparable_player_list = comparable_players['player_names'].tolist()
268
+ except:
269
+ comparable_player_list = []
270
+
271
+ if comparable_player_list:
272
+ # Find which column contains the exposure_player
273
  if specific_columns != []:
274
+ row_data = working_frame.iloc[row][specific_columns]
275
+ working_columns = specific_columns
276
  else:
277
+ row_data = working_frame.iloc[row]
278
+ working_columns = working_frame.columns
279
 
280
+ # Track if we successfully made a replacement
281
+ replacement_made = False
282
+
283
+ # For exposure_target == 0, replace ALL occurrences of exposure_player in this row
284
+ if exposure_target == 0:
285
+ for col in working_columns:
286
+ if row_data[col] == exposure_player:
287
+ # Try to find a suitable replacement for this specific column
288
+ suitable_replacements = []
289
+ for candidate in comparable_player_list:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290
  # Get the replacement player's positions
291
+ replacement_player_positions = projections_df[projections_df['player_names'] == candidate]['position'].iloc[0].split('/')
292
 
293
  # Check if the replacement player is eligible for this column
294
  if type_var == 'Classic':
295
  if check_position_eligibility(sport_var, col, replacement_player_positions):
296
+ suitable_replacements.append(candidate)
 
 
297
  else:
298
+ suitable_replacements.append(candidate)
299
+
300
+ if suitable_replacements:
301
+ insert_player = random.choice(suitable_replacements)
302
+ working_frame.at[row, col] = insert_player
303
+ replacement_made = True
304
+ # Remove this player from the list to avoid duplicates in the same row
305
+ comparable_player_list = [p for p in comparable_player_list if p != insert_player]
306
+ else:
307
+ # Original logic for non-zero exposure targets
308
+ for col in working_columns:
309
+ if row_data[col] == exposure_player:
310
+ insert_player = random.choice(comparable_player_list)
311
+ # Get the replacement player's positions
312
+ replacement_player_positions = projections_df[projections_df['player_names'] == insert_player]['position'].iloc[0].split('/')
313
+
314
+ # Check if the replacement player is eligible for this column
315
+ if type_var == 'Classic':
316
+ if check_position_eligibility(sport_var, col, replacement_player_positions):
317
  working_frame.at[row, col] = insert_player
318
  replacement_made = True
319
  break
320
+ else:
321
+ working_frame.at[row, col] = insert_player
322
+ replacement_made = True
323
+ break
324
+
325
+ # Only increment counter if we actually made a replacement
326
+ if replacement_made:
327
+ change_counter += 1
328
+
329
+ # If we've run out of rows to try, break to avoid infinite loop
330
+ if not random_row_indices_insert:
331
+ break
332
  else:
333
  for row in random_row_indices_replace:
334
  if change_counter < math.ceil(lineups_to_add):