euromod_linking.methods.cells ============================= .. py:module:: euromod_linking.methods.cells .. autoapi-nested-parse:: Shared cell machinery for method methodologies. Turns shock-table group strings into population cells on the input microdata: dimension label derivation, region-level collapse, op semantics, and period resolution. Used by every methodology; lives outside any single method. Attributes ---------- .. autoapisummary:: euromod_linking.methods.cells.CELL_COL Functions --------- .. autoapisummary:: euromod_linking.methods.cells.apply_op euromod_linking.methods.cells.collapse_shock_groups euromod_linking.methods.cells.data_region_len euromod_linking.methods.cells.prepare_cells euromod_linking.methods.cells.resolve_period euromod_linking.methods.cells.specs_in_shocks Module Contents --------------- .. py:function:: apply_op(current: float, op: str, value: float) -> float .. py:function:: collapse_shock_groups(shocks: pandas.DataFrame, used, region_len: int, allow_coarser: bool = False, intensive_metrics=frozenset()) -> tuple[pandas.DataFrame, list[str]] Rewrite shock groups to the data's granularity. Region codes finer than the data are truncated to region_len (0 -> drop the region key); values are aggregated per (metric, collapsed group): grow/mult by mean, set/add by sum. Region codes *coarser* than the data are an error by default (count targets cannot be disaggregated); with allow_coarser=True they are kept as-is for the caller to prefix-match (broadcast semantics — correct for scaling). Why mean vs sum: growth rates and multipliers are *intensive* quantities — merging two NUTS-2 rates into their NUTS-1 parent takes an average, with equal weights, since without subregional population counts in the microdata there is no defensible weighting. Levels and absolute deltas (set/add) are *extensive* — subregional amounts add up. ``intensive_metrics`` names metrics that are intensive whatever the op — rates, where a value is a share or a percentage-point change. Without it a ``set``/``add`` on a rate would be summed, so two NUTS-2 shocks of -3.5pp would become -7pp in their NUTS-1 parent: silently double the intended size. .. py:function:: data_region_len(df: pandas.DataFrame, used) -> int Representative code length of the data's region labels (0 = country). .. py:function:: prepare_cells(df: pandas.DataFrame, used: dict[str, list[str]]) -> tuple[pandas.DataFrame, dict] Add per-key label columns (_dim_) + CELL_COL, labelling each row with the value spec it satisfies. Returns (df, info). .. py:function:: resolve_period(shocks: pandas.DataFrame, params: dict) -> str The period whose shocks to apply: params['period'] when given, else the table's single distinct period; ambiguity is an error listing the options. .. py:function:: specs_in_shocks(shocks: pandas.DataFrame) -> dict[str, list[str]] Group key -> sorted distinct value specs used across (non-constant) shocks. Cells are defined by the shock table itself: the specs a scenario actually uses (e.g. deh: ["0-2", "3-4"]) become that variable's categories for this run. Nothing is recoded ahead of time, so any input variable works and the labels stay readable in the diagnostics. .. py:data:: CELL_COL :value: '_cell'