@@ -468,3 +468,78 @@ def nearest_node_index(node, nodes):
468468 deltas = nodes - node
469469 dist_2 = np .einsum ("ij,ij->i" , deltas , deltas )
470470 return np .argmin (dist_2 )
471+
472+
473+ def drop_unused_chooser_columns (
474+ choosers , spec , locals_d , custom_chooser , sharrow_enabled = False
475+ ):
476+ """
477+ Drop unused columns from the chooser table, based on the spec and custom_chooser function.
478+ """
479+ # keep only variables needed for spec
480+ import re
481+
482+ # define a regular expression to find variables in spec
483+ pattern = r"[a-zA-Z_][a-zA-Z0-9_]*"
484+
485+ unique_variables_in_spec = set (
486+ spec .reset_index ()["Expression" ].apply (lambda x : re .findall (pattern , x )).sum ()
487+ )
488+
489+ if locals_d :
490+ unique_variables_in_spec .add (locals_d .get ("orig_col_name" , None ))
491+ unique_variables_in_spec .add (locals_d .get ("dest_col_name" , None ))
492+ if locals_d .get ("timeframe" ) == "trip" :
493+ orig_col_name = locals_d .get ("ORIGIN" , None )
494+ dest_col_name = locals_d .get ("DESTINATION" , None )
495+ stop_col_name = None
496+ parking_col_name = locals_d .get ("PARKING" , None )
497+ primary_origin_col_name = None
498+ if orig_col_name is None and "od_skims" in locals_d :
499+ orig_col_name = locals_d ["od_skims" ].orig_key
500+ if dest_col_name is None and "od_skims" in locals_d :
501+ dest_col_name = locals_d ["od_skims" ].dest_key
502+ if stop_col_name is None and "dp_skims" in locals_d :
503+ stop_col_name = locals_d ["dp_skims" ].dest_key
504+ if primary_origin_col_name is None and "dnt_skims" in locals_d :
505+ primary_origin_col_name = locals_d ["dnt_skims" ].dest_key
506+ unique_variables_in_spec .add (orig_col_name )
507+ unique_variables_in_spec .add (dest_col_name )
508+ unique_variables_in_spec .add (parking_col_name )
509+ unique_variables_in_spec .add (primary_origin_col_name )
510+ unique_variables_in_spec .add (stop_col_name )
511+ unique_variables_in_spec .add ("trip_period" )
512+ # when using trip_scheduling_choice for trup scheduling
513+ unique_variables_in_spec .add ("last_outbound_stop" )
514+ unique_variables_in_spec .add ("last_inbound_stop" )
515+
516+ # when sharrow mode, need to keep the following columns in the choosers table
517+ if sharrow_enabled :
518+ unique_variables_in_spec .add ("out_period" )
519+ unique_variables_in_spec .add ("in_period" )
520+ unique_variables_in_spec .add ("purpose_index_num" )
521+
522+ if custom_chooser :
523+ import inspect
524+
525+ custom_chooser_lines = inspect .getsource (custom_chooser )
526+ unique_variables_in_spec .update (re .findall (pattern , custom_chooser_lines ))
527+
528+ logger .info ("Dropping unused variables in chooser table" )
529+
530+ logger .info (
531+ "before dropping, the choosers table has {} columns: {}" .format (
532+ len (choosers .columns ), choosers .columns
533+ )
534+ )
535+
536+ # keep only variables needed for spec
537+ choosers = choosers [[c for c in choosers .columns if c in unique_variables_in_spec ]]
538+
539+ logger .info (
540+ "after dropping, the choosers table has {} columns: {}" .format (
541+ len (choosers .columns ), choosers .columns
542+ )
543+ )
544+
545+ return choosers
0 commit comments