diff --git a/cf_xarray/accessor.py b/cf_xarray/accessor.py index ed8dea3e..6de5b08a 100644 --- a/cf_xarray/accessor.py +++ b/cf_xarray/accessor.py @@ -2,7 +2,7 @@ import inspect import itertools import warnings -from collections import ChainMap +from collections import ChainMap, Counter from typing import ( Any, Callable, @@ -1298,8 +1298,6 @@ def rename_like( ``other``, that variable will be renamed to match the "longitude" variable in ``other``. - For now, this function only matches ``("latitude", "longitude", "vertical", "time")`` - Parameters ---------- other: DataArray, Dataset @@ -1312,18 +1310,21 @@ def rename_like( ourkeys = self.keys() theirkeys = other.cf.keys() - good_keys = set(_COORD_NAMES) & ourkeys & theirkeys - if not good_keys: - raise ValueError( - "No common coordinate variables between these two objects." - ) - + good_keys = ourkeys & theirkeys renamer = {} for key in good_keys: - ours = _get_axis_coord_single(self._obj, key)[0] - theirs = _get_axis_coord_single(other, key)[0] - renamer[ours] = theirs + ours = apply_mapper( + (_get_axis_coord, _get_with_standard_name), self._obj, key, error=False + ) + theirs = apply_mapper( + (_get_axis_coord, _get_with_standard_name), other, key, error=False + ) + if len(ours) > 1 or len(theirs) > 1: + continue + renamer[ours[0]] = theirs[0] + count = Counter(renamer.values()) + renamer = {k: v for k, v in renamer.items() if count[v] == 1} newobj = self._obj.rename(renamer) # rename variable names in the coordinates attribute diff --git a/cf_xarray/datasets.py b/cf_xarray/datasets.py index 4e9e6c7b..5e6df446 100644 --- a/cf_xarray/datasets.py +++ b/cf_xarray/datasets.py @@ -122,7 +122,7 @@ romsds["temp"] = ( ("ocean_time", "s_rho"), [np.linspace(20, 30, 30)] * 2, - {"coordinates": "z_rho_dummy"}, + {"coordinates": "z_rho_dummy", "standard_name": "sea_water_potential_temperature"}, ) romsds["temp"].encoding["coordinates"] = "s_rho" romsds.coords["z_rho_dummy"] = ( diff --git a/cf_xarray/tests/test_accessor.py b/cf_xarray/tests/test_accessor.py index 138c6290..91fc353c 100644 --- a/cf_xarray/tests/test_accessor.py +++ b/cf_xarray/tests/test_accessor.py @@ -214,10 +214,13 @@ def test_getitem_ancillary_variables(): def test_rename_like(): original = popds.copy(deep=True) - with pytest.raises(KeyError): - popds.cf.rename_like(airds) + # it'll match for axis: X (lon, nlon) and coordinate="longitude" (lon, TLONG) + # so delete the axis attributes + newair = airds.copy(deep=True) + del newair.lon.attrs["axis"] + del newair.lat.attrs["axis"] - renamed = popds.cf["TEMP"].cf.rename_like(airds) + renamed = popds.cf["TEMP"].cf.rename_like(newair) for k in ["TLONG", "TLAT"]: assert k not in renamed.coords assert k in original.coords @@ -227,6 +230,20 @@ def test_rename_like(): assert "lat" in renamed.coords assert renamed.attrs["coordinates"] == "lon lat" + # standard name matching + newroms = romsds.expand_dims(latitude=[1], longitude=[1]).cf.guess_coord_axis() + renamed = popds.cf["UVEL"].cf.rename_like(newroms) + assert renamed.attrs["coordinates"] == "longitude latitude" + assert "longitude" in renamed.coords + assert "latitude" in renamed.coords + assert "ULON" not in renamed.coords + assert "ULAT" not in renamed.coords + + # should change "temp" to "TEMP" + renamed = romsds.cf.rename_like(popds) + assert "temp" not in renamed + assert "TEMP" in renamed + @pytest.mark.parametrize("obj", objects) @pytest.mark.parametrize( diff --git a/doc/whats-new.rst b/doc/whats-new.rst index e6be6541..7d900984 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -10,7 +10,7 @@ v0.4.1 (unreleased) - Automatically set ``x`` or ``y`` for :py:attr:`DataArray.cf.plot`. By `Deepak Cherian`_. - Added scripts to document :ref:`criteria` with tables. By `Mattia Almansi`_. - Support for ``.drop()``, ``.drop_vars()``, ``.drop_sel()``, ``.drop_dims()``, ``.set_coords()``, ``.reset_coords()``. By `Mattia Almansi`_. -- Support for using ``standard_name`` in more functions. (:pr:`128`) By `Deepak Cherian`_ +- Support for using ``standard_name`` in more functions. (:pr:`128`, :pr:`165`) By `Deepak Cherian`_ - Allow :py:meth:`DataArray.cf.__getitem__` with standard names. By `Deepak Cherian`_ - Rewrite the ``values`` of :py:attr:`Dataset.coords` and :py:attr:`Dataset.data_vars` with objects returned by :py:meth:`Dataset.cf.__getitem__`. This allows extraction of DataArrays when there are clashes