Skip to content

Commit a2ad2a1

Browse files
authored
Merge pull request #790 from ActivitySim/veh_type_alts_filter_fix
Vehicle Type Alts Filtering Bug Fix
2 parents bdc9cac + 3521c8d commit a2ad2a1

File tree

2 files changed

+74
-3
lines changed

2 files changed

+74
-3
lines changed
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# ActivitySim
2+
# See full license in LICENSE.txt.
3+
4+
import pandas as pd
5+
import pandas.testing as pdt
6+
7+
from activitysim.abm.models.vehicle_type_choice import (
8+
get_combinatorial_vehicle_alternatives,
9+
construct_model_alternatives,
10+
VehicleTypeChoiceSettings,
11+
)
12+
from activitysim.core import workflow
13+
14+
15+
def test_vehicle_type_alts():
16+
state = workflow.State.make_default(__file__)
17+
18+
alts_cats_dict = {
19+
"body_type": ["Car", "SUV"],
20+
"fuel_type": ["Gas", "BEV"],
21+
"age": [1, 2, 3],
22+
}
23+
24+
alts_wide, alts_long = get_combinatorial_vehicle_alternatives(alts_cats_dict)
25+
26+
# alts are initially constructed combinatorially
27+
assert len(alts_long) == 12, "alts_long should have 12 rows"
28+
assert len(alts_wide) == 12, "alts_wide should have 12 rows"
29+
30+
model_settings = VehicleTypeChoiceSettings.model_construct()
31+
model_settings.combinatorial_alts = alts_cats_dict
32+
model_settings.PROBS_SPEC = None
33+
model_settings.WRITE_OUT_ALTS_FILE = False
34+
35+
# constructing veh type data with missing alts
36+
vehicle_type_data = pd.DataFrame(
37+
data={
38+
"body_type": ["Car", "Car", "Car", "SUV", "SUV"],
39+
"fuel_type": ["Gas", "Gas", "BEV", "Gas", "BEV"],
40+
"age": ["1", "2", "3", "1", "2"],
41+
"dummy_data": [1, 2, 3, 4, 5],
42+
},
43+
index=[0, 1, 2, 3, 4],
44+
)
45+
46+
alts_wide, alts_long = construct_model_alternatives(
47+
state, model_settings, alts_cats_dict, vehicle_type_data
48+
)
49+
50+
# should only have alts left that are in the file
51+
assert len(alts_long) == 5, "alts_long should have 5 rows"
52+
53+
# indexes need to be the same to choices match alts
54+
pdt.assert_index_equal(alts_long.index, alts_wide.index)
55+
56+
# columns need to be in correct order for downstream configs
57+
pdt.assert_index_equal(
58+
alts_long.columns, pd.Index(["body_type", "age", "fuel_type"])
59+
)

activitysim/abm/models/vehicle_type_choice.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,19 @@ def construct_model_alternatives(
244244
), f"missing vehicle data for alternatives:\n {missing_alts}"
245245
else:
246246
# eliminate alternatives if no vehicle type data
247+
num_alts_before_filer = len(alts_wide)
247248
alts_wide = alts_wide[alts_wide._merge != "left_only"]
249+
logger.warning(
250+
f"Removed {num_alts_before_filer - len(alts_wide)} alternatives not included in input vehicle type data."
251+
)
252+
# need to also remove any alts from alts_long
253+
alts_long.set_index(["body_type", "age", "fuel_type"], inplace=True)
254+
alts_long = alts_long[
255+
alts_long.index.isin(
256+
alts_wide.set_index(["body_type", "age", "fuel_type"]).index
257+
)
258+
].reset_index()
259+
alts_long.index = alts_wide.index
248260
alts_wide.drop(columns="_merge", inplace=True)
249261

250262
# converting age to integer to allow interactions in utilities
@@ -455,11 +467,11 @@ def iterate_vehicle_type_choice(
455467
alts = (
456468
alts_long[alts_long.columns]
457469
.apply(lambda row: "_".join(row.values.astype(str)), axis=1)
458-
.values
470+
.to_dict()
459471
)
460472
else:
461-
alts = model_spec.columns
462-
choices["vehicle_type"] = choices["vehicle_type"].map(dict(enumerate(alts)))
473+
alts = enumerate(dict(model_spec.columns))
474+
choices["vehicle_type"] = choices["vehicle_type"].map(alts)
463475

464476
# STEP II: append probabilistic vehicle type attributes
465477
if probs_spec_file is not None:

0 commit comments

Comments
 (0)