Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support swap_dims to dimension names that are not existing variables #3636

Merged
merged 7 commits into from
Jan 8, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ New Features
- Added the ``count`` reduction method to both :py:class:`~core.rolling.DatasetCoarsen`
and :py:class:`~core.rolling.DataArrayCoarsen` objects. (:pull:`3500`)
By `Deepak Cherian <https://github.com/dcherian>`_
- :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 <https://github.com/keewis>`_.
- Extend :py:class:`core.accessor_dt.DatetimeAccessor` properties
and support `.dt` accessor for timedelta
via :py:class:`core.accessor_dt.TimedeltaAccessor` (:pull:`3612`)
Expand Down
10 changes: 8 additions & 2 deletions xarray/core/dataarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
-------
Expand All @@ -1504,6 +1503,13 @@ def swap_dims(self, dims_dict: Mapping[Hashable, Hashable]) -> "DataArray":
Coordinates:
x (y) <U1 'a' 'b'
* y (y) int64 0 1
>>> arr.swap_dims({"x": "z"})
<xarray.DataArray (z: 2)>
array([0, 1])
Coordinates:
x (z) <U1 'a' 'b'
y (z) int64 0 1
Dimensions without coordinates: z

See Also
--------
Expand Down
17 changes: 13 additions & 4 deletions xarray/core/dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -2868,8 +2868,7 @@ def swap_dims(
----------
dims_dict : dict-like
Dictionary whose keys are current dimension names and whose values
are new names. Each value must already be a variable in the
dataset.
are new names.

Returns
-------
Expand Down Expand Up @@ -2898,6 +2897,16 @@ def swap_dims(
Data variables:
a (y) int64 5 7
b (y) float64 0.1 2.4
>>> ds.swap_dims({"x": "z"})
<xarray.Dataset>
Dimensions: (z: 2)
Coordinates:
x (z) <U1 'a' 'b'
y (z) int64 0 1
Dimensions without coordinates: z
Data variables:
a (z) int64 5 7
b (z) float64 0.1 2.4

See Also
--------
Expand All @@ -2914,7 +2923,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)
Expand All @@ -2923,7 +2932,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] = {}
Expand Down
5 changes: 5 additions & 0 deletions xarray/tests/test_dataarray.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
6 changes: 6 additions & 0 deletions xarray/tests/test_dataset.py
Original file line number Diff line number Diff line change
Expand Up @@ -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(
{
Expand Down