add_secondary_demand

site.SiteProblem.add_secondary_demand(
    demand_df,
    demand_col,
    location_id_col,
    label,
    skip_cols=None,
    also_weight_matrices=None,
)

Register an additional demand scenario (e.g. projected future demand alongside a primary current-demand dataset).

Unlike add_demand(), a secondary demand scenario never drives the optimisation objective – the primary demand set via add_demand() (or the equal-demand fallback) always drives site selection and search/pruning. Instead, each registered secondary demand scenario contributes its own weighted_average__<label> and proportion_within_coverage_threshold__<label> metric columns – the two metrics that actually change with demand – into every solution solve() produces, so it can be used directly in plots, Metric(column=...), ranking (sort_by= "weighted_average__future_demand" post-hoc, or solve(rank_on="weighted_average__future_demand") to search on it directly), or blended into the optimisation objective via weights={"future_demand": ...}.

By default a secondary demand scenario only re-weights the primary travel matrix. Pass also_weight_matrices to additionally compute weighted_average__<travel_label>__<label> / proportion_within_coverage_threshold__<travel_label>__<label> against one or more registered secondary travel matrices – this is opt-in because the combination of secondary travel and secondary demand matrices grows the output multiplicatively.

You may call this method multiple times with different labels to register as many demand scenarios as needed. Each one adds approximately the cost of one extra weighted-average/coverage pass over the primary matrix (plus one per named also_weight_matrices entry), so solve() time scales close to linearly with the number of secondary demand scenarios registered.

Parameters

Name Type Description Default
demand_df pandas.DataFrame or geopandas.GeoDataFrame or str The dataset containing demand for this scenario, or a local or web path to its location. required
demand_col str The name of the column in demand_df representing the quantity of demand for this scenario. required
location_id_col str The name of the column in demand_df used as a unique identifier for demand locations (should correspond to IDs in the primary demand data). required
label str A unique label identifying this demand scenario, used to suffix every metric column it produces (e.g. label="future_demand" -> weighted_average__future_demand). Must be non-empty, must not contain "__", and must not already be registered as either a secondary demand scenario or a secondary travel matrix (suffix labels are shared between the two). required
skip_cols list of str A list of column names to ignore during data loading. None
also_weight_matrices list of str Labels of registered secondary travel matrices (via add_secondary_travel_matrix()) to also weight by this demand scenario, producing <metric>__<travel_label>__<label> columns. Order of registration does not matter – membership is checked when solve() builds the aligned frames. None

Returns

Name Type Description
None

Raises

Name Type Description
ValueError If label is empty, contains "__", or has already been registered (as a secondary demand scenario or secondary travel matrix).
KeyError If demand_col or location_id_col is missing from the provided dataframe.

Notes

Secondary demand scenarios must be complete: every demand location present in the primary demand/travel data must have a non-missing value. This is validated when solve() builds the aligned per-solution frames (not here, since the primary demand/travel matrix may not yet be registered).

Back to top