You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Simulation(dataset=DataFrame) fails when a household or benefit unit has more than one person #2266
Simulation(dataset=<pandas DataFrame>) raises ValueError when any benefit unit or household has more than one person and the frame holds a benefit unit or household column (including the identifier columns it needs).
ValueError: Unable to set value "[1 1]" for variable "benunit_id", as its length is 2 while there are 1 benunits in the simulation.
The same happens for a frame exported with to_input_dataframe() from a simulation built on a dataset with multi-person households (Unable to set value ... for variable "rent", as its length is 12 while there are 6 households).
Cause, read in the code
Simulation.build_from_dataframe (policyengine_uk/simulation.py) takes a frame with one row per person and columns named variable__period, the format to_input_dataframe() exports. It builds the entities with build_from_ids, then calls self.set_input(variable, time_period, df[column]) for every column. For a benefit unit or household variable the column still has one value per person, so its length is wrong unless every benefit unit and household has exactly one person.
policyengine-core's own loader for this format takes each group's value from its first member (population.value_from_first_person).
A second, smaller problem in the same function: get_first_array finds a column with df.columns.str.contains(variable_name + "__"), so household_id__ also matches person_household_id__2025 and benunit_id__ matches person_benunit_id__2025. build_from_ids passes the result through np.unique, so today either column gives the same entities, but the match should be exact.
Suggested fix
For a variable whose entity is not the person, set population.value_from_first_person(values), and match column names exactly (column.split("__")[0] == variable_name). Add a test that a frame with a multi-person household builds and that a dataset-built simulation's to_input_dataframe() loads back with the same results.
Found while fixing #2254 (PR #2265 does not depend on it).
Activity
Merge origin/main (6d89338) into esa-jsa-remunerative-work