diff --git a/cf_xarray/accessor.py b/cf_xarray/accessor.py index 35692bfc..5be0efbd 100644 --- a/cf_xarray/accessor.py +++ b/cf_xarray/accessor.py @@ -1261,7 +1261,9 @@ def _maybe_to_dataarray(self, obj=None): return obj def rename_like( - self, other: Union[DataArray, Dataset] + self, + other: Union[DataArray, Dataset], + skip: Union[str, Iterable[str]] = None, ) -> Union[DataArray, Dataset]: """ Renames variables in object to match names of like-variables in ``other``. @@ -1277,20 +1279,30 @@ def rename_like( ---------- other : DataArray, Dataset Variables will be renamed to match variable names in this xarray object + skip: str, Iterable[str], optional + Limit the renaming excluding + ("axes", "cell_measures", "coordinates", "standard_names") + or a subset thereof. Returns ------- DataArray or Dataset with renamed variables """ + skip = [skip] if isinstance(skip, str) else skip or [] + ourkeys = self.keys() theirkeys = other.cf.keys() good_keys = ourkeys & theirkeys keydict = {} for key in good_keys: - ours = _get_all(self._obj, key) - theirs = _get_all(other, key) - keydict[key] = dict(ours=ours, theirs=theirs) + ours = set(_get_all(self._obj, key)) + theirs = set(_get_all(other, key)) + for attr in skip: + ours -= set(getattr(self, attr).get(key, [])) + theirs -= set(getattr(other.cf, attr).get(key, [])) + if ours and theirs: + keydict[key] = dict(ours=list(ours), theirs=list(theirs)) conflicts = {} for k0, v0 in keydict.items(): @@ -1299,7 +1311,7 @@ def rename_like( continue for v1 in keydict.values(): # Conflicts have same ours but different theirs or vice versa - if sum([v0["ours"] == v1["ours"], v0["theirs"] == v1["theirs"]]) == 1: + if (v0["ours"] == v1["ours"]) != (v0["theirs"] == v1["theirs"]): conflicts[k0] = v0 break if conflicts: diff --git a/cf_xarray/tests/test_accessor.py b/cf_xarray/tests/test_accessor.py index 71d35441..bab850a9 100644 --- a/cf_xarray/tests/test_accessor.py +++ b/cf_xarray/tests/test_accessor.py @@ -250,8 +250,14 @@ def test_rename_like(): assert "TEMP" in renamed # skip conflicting variables + da = popds.cf["TEMP"] with pytest.warns(UserWarning, match="Conflicting variables skipped:.*"): - popds.cf.rename_like(airds) + expected = {"longitude": ["TLONG"], "latitude": ["TLAT"]} + actual = da.cf.rename_like(airds).cf.coordinates + assert expected == actual + expected = {"longitude": ["lon"], "latitude": ["lat"]} + actual = da.cf.rename_like(airds, skip="axes").cf.coordinates + assert expected == actual @pytest.mark.parametrize("obj", objects) diff --git a/doc/examples/introduction.ipynb b/doc/examples/introduction.ipynb index 290444f8..1a2a38ef 100644 --- a/doc/examples/introduction.ipynb +++ b/doc/examples/introduction.ipynb @@ -605,10 +605,10 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "If we drop the `X` and `Y` axes, a one-to-one mapping is possible. In this\n", - "example, `TLONG` and `TLAT` are renamed to `lon` and `lat` i.e. their\n", - "counterparts in `ds`. Note the the `coordinates` attribute is appropriately\n", - "changed.\n" + "If we exclude all axes (variables with `axis` attribute), a one-to-one mapping\n", + "is possible. In this example, `TLONG` and `TLAT` are renamed to `lon` and `lat`\n", + "i.e. their counterparts in `ds`. Note the the `coordinates` attribute is\n", + "appropriately changed.\n" ] }, { @@ -622,8 +622,7 @@ }, "outputs": [], "source": [ - "da = da.cf.drop_vars([\"X\", \"Y\"])\n", - "da.cf.rename_like(ds)" + "da.cf.rename_like(ds, skip=\"axes\")" ] }, {