From 29c08c4d218bdaf5e3da3e2ccb044e4a183ea9cc Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 17 Dec 2019 15:06:43 +0100 Subject: [PATCH 1/5] test that swapping to a non-existing name works --- xarray/tests/test_dataarray.py | 5 +++++ xarray/tests/test_dataset.py | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/xarray/tests/test_dataarray.py b/xarray/tests/test_dataarray.py index f957316d8ac..4189c3b504a 100644 --- a/xarray/tests/test_dataarray.py +++ b/xarray/tests/test_dataarray.py @@ -1530,6 +1530,11 @@ def test_swap_dims(self): actual = array.swap_dims({"x": "y"}) assert_identical(expected, actual) + array = DataArray(np.random.randn(3), {"x": list("abc")}, "x") + expected = DataArray(array.values, {"x": ("y", list("abc"))}, dims="y") + actual = array.swap_dims({"x": "y"}) + assert_identical(expected, actual) + def test_expand_dims_error(self): array = DataArray( np.random.randn(3, 4), diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py index 7db1911621b..9a029121a10 100644 --- a/xarray/tests/test_dataset.py +++ b/xarray/tests/test_dataset.py @@ -2525,6 +2525,12 @@ def test_swap_dims(self): with raises_regex(ValueError, "replacement dimension"): original.swap_dims({"x": "z"}) + expected = Dataset( + {"y": ("u", list("abc")), "z": 42}, coords={"x": ("u", [1, 2, 3])} + ) + actual = original.swap_dims({"x": "u"}) + assert_identical(expected, actual) + def test_expand_dims_error(self): original = Dataset( { From 7599faf9bcb14876cdf04a6a1c184fb7a0901797 Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 17 Dec 2019 15:32:03 +0100 Subject: [PATCH 2/5] don't try to get a variable if the variable does not exist --- xarray/core/dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 6be06fed117..b8e532c7098 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -2914,7 +2914,7 @@ def swap_dims( "cannot swap from dimension %r because it is " "not an existing dimension" % k ) - if self.variables[v].dims != (k,): + if v in self.variables and self.variables[v].dims != (k,): raise ValueError( "replacement dimension %r is not a 1D " "variable along the old dimension %r" % (v, k) From 3f57bf3763fbb12149bb87d55e65f12678fef35a Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 17 Dec 2019 15:54:48 +0100 Subject: [PATCH 3/5] don't add dimensions to coord_names if they are not existing variables --- xarray/core/dataset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index b8e532c7098..b21b75bfa21 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -2923,7 +2923,7 @@ def swap_dims( result_dims = {dims_dict.get(dim, dim) for dim in self.dims} coord_names = self._coord_names.copy() - coord_names.update(dims_dict.values()) + coord_names.update({dim for dim in dims_dict.values() if dim in self.variables}) variables: Dict[Hashable, Variable] = {} indexes: Dict[Hashable, pd.Index] = {} From be6d69e71378da0f9f53f9d2f07cdd97d699f00f Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 17 Dec 2019 16:01:20 +0100 Subject: [PATCH 4/5] add whats-new.rst entry --- doc/whats-new.rst | 3 +++ 1 file changed, 3 insertions(+) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 44bff9e7202..9dfc5d35a8b 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -31,6 +31,9 @@ New Features - Added the :py:meth:`count` reduction method to both :py:class:`DatasetCoarsen` and :py:class:`DataArrayCoarsen` objects. (:pull:`3500`) By `Deepak Cherian `_ +- :py:meth:`Dataset.swap_dims` and :py:meth:`DataArray.swap_dims` + now allow swapping to dimension names that don't exist yet. (:pull:`3636`) + By `Justus Magin `_. Bug fixes ~~~~~~~~~ From 605d564bb68d2e0c88d6949703c0b7d9d4bbeede Mon Sep 17 00:00:00 2001 From: Keewis Date: Tue, 17 Dec 2019 16:04:53 +0100 Subject: [PATCH 5/5] update the documentation --- xarray/core/dataarray.py | 10 ++++++++-- xarray/core/dataset.py | 13 +++++++++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index 31cd3c713f6..54dc9434917 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -1480,8 +1480,7 @@ def swap_dims(self, dims_dict: Mapping[Hashable, Hashable]) -> "DataArray": ---------- dims_dict : dict-like Dictionary whose keys are current dimension names and whose values - are new names. Each value must already be a coordinate on this - array. + are new names. Returns ------- @@ -1504,6 +1503,13 @@ def swap_dims(self, dims_dict: Mapping[Hashable, Hashable]) -> "DataArray": Coordinates: x (y) >> arr.swap_dims({"x": "z"}) + + array([0, 1]) + Coordinates: + x (z) >> ds.swap_dims({"x": "z"}) + + Dimensions: (z: 2) + Coordinates: + x (z)