diff --git a/CHANGELOG.md b/CHANGELOG.md index 7dc6793de0..8c1401339d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -31,6 +31,7 @@ Code freeze date: YYYY-MM-DD ### Changed +- `Centroids.append` now takes multiple arguments and provides a performance boost when doing so [#989](https://github.com/CLIMADA-project/climada_python/pull/989) - `climada.util.coordinates.get_country_geometries` function: Now throwing a ValueError if unregognized ISO country code is given (before, the invalid ISO code was ignored) [#980](https://github.com/CLIMADA-project/climada_python/pull/980) - Improved scaling factors implemented in `climada.hazard.trop_cyclone.apply_climate_scenario_knu` to model the impact of climate changes to tropical cyclones [#734](https://github.com/CLIMADA-project/climada_python/pull/734) - In `climada.util.plot.geo_im_from_array`, NaNs are plotted in gray while cells with no centroid are not plotted [#929](https://github.com/CLIMADA-project/climada_python/pull/929) @@ -47,6 +48,7 @@ Code freeze date: YYYY-MM-DD ### Fixed +- Resolved an issue where windspeed computation was much slower than in Climada v3 [#989](https://github.com/CLIMADA-project/climada_python/pull/989) - File handles are being closed after reading netcdf files with `climada.hazard` modules [#953](https://github.com/CLIMADA-project/climada_python/pull/953) - Avoids a ValueError in the impact calculation for cases with a single exposure point and MDR values of 0, by explicitly removing zeros in `climada.hazard.Hazard.get_mdr` [#933](https://github.com/CLIMADA-project/climada_python/pull/948) diff --git a/climada/hazard/centroids/centr.py b/climada/hazard/centroids/centr.py index b0c6365c7e..c4044f7dd5 100644 --- a/climada/hazard/centroids/centr.py +++ b/climada/hazard/centroids/centr.py @@ -331,11 +331,16 @@ def from_pnt_bounds(cls, points_bounds, res, crs=DEF_CRS): } ) - def append(self, centr): - """Append Centroids + def append(self, *centr): + """Append Centroids to the current centroid object for concatenation. + + This method checks that all centroids use the same CRS, appends the list of centroids to + the initial Centroid object and eventually concatenates them to create a single centroid + object with the union of all centroids. Note that the result might contain duplicate points if the object to append has an overlap - with the current object. + with the current object. Remove duplicates by either using :py:meth:`union` + or calling :py:meth:`remove_duplicate_points` after appending. Parameters ---------- @@ -351,22 +356,25 @@ def append(self, centr): union : Union of Centroid objects. remove_duplicate_points : Remove duplicate points in a Centroids object. """ - if not u_coord.equal_crs(self.crs, centr.crs): - raise ValueError( - f"The given centroids use different CRS: {self.crs}, {centr.crs}. " - "The centroids are incompatible and cannot be concatenated." - ) - self.gdf = pd.concat([self.gdf, centr.gdf]) + for other in centr: + if not u_coord.equal_crs(self.crs, other.crs): + raise ValueError( + f"The given centroids use different CRS: {self.crs}, {other.crs}. " + "The centroids are incompatible and cannot be concatenated." + ) + self.gdf = pd.concat([self.gdf] + [other.gdf for other in centr]) def union(self, *others): - """Create the union of Centroids objects + """Create the union of the current Centroids object with one or more other centroids + objects by passing the list of centroids to :py:meth:`append` for concatenation and then + removes duplicates. All centroids must have the same CRS. Points that are contained in more than one of the Centroids objects will only be contained once (i.e. duplicates are removed). Parameters ---------- - others : list of Centroids + others : Centroids Centroids contributing to the union. Returns @@ -375,8 +383,8 @@ def union(self, *others): Centroids object containing the union of all Centroids. """ centroids = copy.deepcopy(self) - for cent in others: - centroids.append(cent) + centroids.append(*others) + return centroids.remove_duplicate_points() def remove_duplicate_points(self): diff --git a/climada/hazard/centroids/test/test_centr.py b/climada/hazard/centroids/test/test_centr.py index 778d9383ef..0e36693719 100644 --- a/climada/hazard/centroids/test/test_centr.py +++ b/climada/hazard/centroids/test/test_centr.py @@ -816,6 +816,20 @@ def test_append_dif_crs(self): with self.assertRaises(ValueError): self.centr.append(centr2) + def test_append_multiple_arguments(self): + """Test passing append() multiple arguments in the form of a list of Centroids.""" + # create a single centroid + lat, lon = np.array([1, 2]), np.array([1, 2]) + centr = Centroids(lat=lat, lon=lon) + # create a list of centroids + coords = [(np.array([3, 4]), np.array([3, 4]))] + centroids_list = [Centroids(lat=lat, lon=lon) for lat, lon in coords] + + centr.append(*centroids_list) + + np.testing.assert_array_equal(centr.lat, [1, 2, 3, 4]) + np.testing.assert_array_equal(centr.lon, [1, 2, 3, 4]) + def test_remove_duplicate_pass(self): """Test remove_duplicate_points""" centr = Centroids(