From 10ab1237ce77ee518d56e0c8fbf65eaf43523153 Mon Sep 17 00:00:00 2001 From: Maximilian Roos Date: Sat, 14 Oct 2023 12:23:39 -0700 Subject: [PATCH] . --- xarray/core/dataset.py | 27 +++++++++++++++++++++++---- xarray/tests/test_dataset.py | 9 +++++++-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index b55efadcdb2..076c9f51793 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -10342,15 +10342,34 @@ def resample( def drop_attrs(self) -> Self: """ Removes all attributes from the Dataset and its variables. + + Returns + ------- + Dataset """ # Remove attributes from the dataset self = self._replace(attrs={}) # Remove attributes from each variable in the dataset for var in self.variables: - # variables don't have a `._replace` method, so we copy and then remove. If - # we added a `._replace` method, we could use that instead. - self[var] = self[var].copy() - self[var].attrs = {} + # variables don't have a `._replace` method, so we copy and then remove + # attrs. If we added a `._replace` method, we could use that instead. + if var not in self.indexes: + self[var] = self[var].copy() + self[var].attrs = {} + + new_idx_variables = {} + + # Not sure this is the most elegant way of doing this, but it works. + # (Contributions welcome for a more general "map over all variables, including + # indexes" approach.) + for idx, idx_vars in self.xindexes.group_by_index(): + # copy each coordinate variable of an index and drop their attrs + temp_idx_variables = {k: v.copy() for k, v in idx_vars.items()} + for v in temp_idx_variables.values(): + v.attrs = {} + # maybe re-wrap the index object in new coordinate variables + new_idx_variables.update(idx.create_variables(temp_idx_variables)) + self = self.assign(**new_idx_variables) return self diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py index 67de33ba615..fd575a6171c 100644 --- a/xarray/tests/test_dataset.py +++ b/xarray/tests/test_dataset.py @@ -4366,10 +4366,15 @@ def test_drop_attrs(self) -> None: # Doesn't change original assert_identical(ds, original) - # Example with variables and coords with attrs, check they're dropped too + # Example with variables and coords with attrs, and a multiindex. (arguably + # should have used a canonical dataset with all the features we're should + # support...) var = Variable("x", [1, 2, 3], attrs=dict(x=1, y=2)) idx = IndexVariable("y", [1, 2, 3], attrs=dict(c=1, d=2)) - ds = Dataset(dict(var1=var), coords=dict(y=idx)).assign_attrs(a=1, b=2) + mx = xr.Coordinates.from_pandas_multiindex( + pd.MultiIndex.from_tuples([(1, 2), (3, 4)], names=["d", "e"]), "z" + ) + ds = Dataset(dict(var1=var), coords=dict(y=idx, z=mx)).assign_attrs(a=1, b=2) assert ds.coords["y"].attrs != {} original = ds.copy(deep=True)