diff --git a/CHANGELOG.md b/CHANGELOG.md index e45d5e3bf..d27831c88 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ Code freeze date: YYYY-MM-DD - `Hazard.from_raster_xarray` now returns a sparse matrix instead of a sparse array [#1261](https://github.com/CLIMADA-project/climada_python/pull/1261). - `ImpactCalc.impact` now raises a clear `ValueError` when the supplied `Hazard` contains no events, instead of failing later inside `np.array_split` with an obscure message [#814](https://github.com/CLIMADA-project/climada_python/issues/814). - Fix TCTracks.from_FAST duplicate loading from year loop [#1269](github.com/CLIMADA-project/climada_python/pull/1269) +- Fix a wrong computation of EAI in the `trajectory` module when the index of the `GeoDataFrame` of an Exposures object is not a 0 to n range. [#1297](https://github.com/CLIMADA-project/climada_python/pull/1297). - `TropCyclone.apply_climate_scenario_knu` now raises a `ValueError` if a frequency is negative [#1338](https://github.com/CLIMADA-project/climada_python/pull/1338). ### Deprecated diff --git a/climada/trajectories/calc_risk_metrics.py b/climada/trajectories/calc_risk_metrics.py index 39c0b8fca..56509c4fd 100644 --- a/climada/trajectories/calc_risk_metrics.py +++ b/climada/trajectories/calc_risk_metrics.py @@ -255,7 +255,12 @@ def calc_eai_gdf(self) -> pd.DataFrame: """ - metric_df = pd.DataFrame(self.per_date_eai, index=self._date_idx) + metric_df = pd.DataFrame( + self.per_date_eai, + index=self._date_idx, + columns=self.snapshots[0].exposure.gdf.index, + ) + metric_df = metric_df.reset_index().melt( id_vars=DATE_COL_NAME, var_name=COORD_ID_COL_NAME, value_name=RISK_COL_NAME ) @@ -868,7 +873,11 @@ def calc_eai_gdf(self) -> pd.DataFrame: (notably for `value` and `group_id`). """ - metric_df = pd.DataFrame(self.per_date_eai, index=self.date_idx) + metric_df = pd.DataFrame( + self.per_date_eai, + index=self._date_idx, + columns=self.snapshot_start.exposure.gdf.index, + ) metric_df = metric_df.reset_index().melt( id_vars=DEFAULT_PERIOD_INDEX_NAME, var_name=COORD_ID_COL_NAME, diff --git a/climada/trajectories/test/conftest.py b/climada/trajectories/test/conftest.py index 57a1d3a27..5ff7e6a64 100644 --- a/climada/trajectories/test/conftest.py +++ b/climada/trajectories/test/conftest.py @@ -39,7 +39,8 @@ EXP_DESC = "Test exposure dataset" EXPOSURE_REF_YEAR = 2020 EXPOSURE_VALUE_UNIT = "USD" -VALUES = np.array([0, 1000, 2000, 3000, 4000, 5000]) +EXPOSURE_INDICES = np.array([0, 1, 2, 7, 8, 5]) +EXPOSURE_VALUES = np.array([0, 1000, 2000, 3000, 4000, 5000]) CATEGORIES = np.array([1, 1, 2, 1, 1, 3]) # Exposure coordinates @@ -60,7 +61,7 @@ # Hazard events EVENT_IDS = np.array([1, 2, 3, 4, 5]) EVENT_NAMES = ["ev1", "ev2", "ev3", "ev4", "ev5"] -DATES = np.array([1, 2, 3, 4, 5]) +DATES = np.array([1, 2, 7, 4, 5]) # Frequency are choosen so that they cumulate nicely # to correspond to 250, 100, 50, and 20y return periods (for impacts) @@ -80,9 +81,9 @@ IMPF_NAME = "IMPF_1" # Sanity checks -for const in [VALUES, CATEGORIES, EXP_LONS, EXP_LATS]: +for const in [EXPOSURE_VALUES, CATEGORIES, EXP_LONS, EXP_LATS]: assert len(const) == len( - VALUES + EXPOSURE_VALUES ), "VALUES, REGIONS, CATEGORIES, EXP_LONS, EXP_LATS should all have the same lengths." for const in [EVENT_IDS, EVENT_NAMES, DATES, FREQUENCY]: @@ -93,7 +94,7 @@ @pytest.fixture(scope="session") def exposure_values(): - return VALUES.copy() + return EXPOSURE_VALUES.copy() @pytest.fixture(scope="session") @@ -124,6 +125,7 @@ def _make_exposures( "geometry": exposure_geometry, }, crs=CRS_WGS84, + index=EXPOSURE_INDICES, ) if group_id is not None: gdf["group_id"] = group_id