Skip to content

Commit 293613e

Browse files
authored
Accept missing_dims in Variable.transpose and Dataset.transpose (#5586)
1 parent bc92331 commit 293613e

File tree

5 files changed

+59
-13
lines changed

5 files changed

+59
-13
lines changed

doc/whats-new.rst

+3
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,9 @@ v0.18.3 (unreleased)
2121

2222
New Features
2323
~~~~~~~~~~~~
24+
- Allow passing argument ``missing_dims`` to :py:meth:`Variable.transpose` and :py:meth:`Dataset.transpose`
25+
(:issue:`5550`, :pull:`5586`)
26+
By `Giacomo Caria <https://github.com/gcaria>`_.
2427
- Allow passing a dictionary as coords to a :py:class:`DataArray` (:issue:`5527`,
2528
reverts :pull:`1539`, which had deprecated this due to python's inconsistent ordering in earlier versions).
2629
By `Sander van Rijn <https://github.com/sjvrijn>`_.

xarray/core/dataset.py

+15-7
Original file line numberDiff line numberDiff line change
@@ -4543,7 +4543,11 @@ def drop_dims(
45434543
drop_vars = {k for k, v in self._variables.items() if set(v.dims) & drop_dims}
45444544
return self.drop_vars(drop_vars)
45454545

4546-
def transpose(self, *dims: Hashable) -> "Dataset":
4546+
def transpose(
4547+
self,
4548+
*dims: Hashable,
4549+
missing_dims: str = "raise",
4550+
) -> "Dataset":
45474551
"""Return a new Dataset object with all array dimensions transposed.
45484552
45494553
Although the order of dimensions on each array will change, the dataset
@@ -4554,6 +4558,12 @@ def transpose(self, *dims: Hashable) -> "Dataset":
45544558
*dims : hashable, optional
45554559
By default, reverse the dimensions on each array. Otherwise,
45564560
reorder the dimensions to this order.
4561+
missing_dims : {"raise", "warn", "ignore"}, default: "raise"
4562+
What to do if dimensions that should be selected from are not present in the
4563+
Dataset:
4564+
- "raise": raise an exception
4565+
- "warn": raise a warning, and ignore the missing dimensions
4566+
- "ignore": ignore the missing dimensions
45574567
45584568
Returns
45594569
-------
@@ -4572,12 +4582,10 @@ def transpose(self, *dims: Hashable) -> "Dataset":
45724582
numpy.transpose
45734583
DataArray.transpose
45744584
"""
4575-
if dims:
4576-
if set(dims) ^ set(self.dims) and ... not in dims:
4577-
raise ValueError(
4578-
f"arguments to transpose ({dims}) must be "
4579-
f"permuted dataset dimensions ({tuple(self.dims)})"
4580-
)
4585+
# Use infix_dims to check once for missing dimensions
4586+
if len(dims) != 0:
4587+
_ = list(infix_dims(dims, self.dims, missing_dims))
4588+
45814589
ds = self.copy()
45824590
for name, var in self._variables.items():
45834591
var_dims = tuple(dim for dim in dims if dim in (var.dims + (...,)))

xarray/core/variable.py

+14-2
Original file line numberDiff line numberDiff line change
@@ -1378,14 +1378,24 @@ def roll(self, shifts=None, **shifts_kwargs):
13781378
result = result._roll_one_dim(dim, count)
13791379
return result
13801380

1381-
def transpose(self, *dims) -> "Variable":
1381+
def transpose(
1382+
self,
1383+
*dims,
1384+
missing_dims: str = "raise",
1385+
) -> "Variable":
13821386
"""Return a new Variable object with transposed dimensions.
13831387
13841388
Parameters
13851389
----------
13861390
*dims : str, optional
13871391
By default, reverse the dimensions. Otherwise, reorder the
13881392
dimensions to this order.
1393+
missing_dims : {"raise", "warn", "ignore"}, default: "raise"
1394+
What to do if dimensions that should be selected from are not present in the
1395+
Variable:
1396+
- "raise": raise an exception
1397+
- "warn": raise a warning, and ignore the missing dimensions
1398+
- "ignore": ignore the missing dimensions
13891399
13901400
Returns
13911401
-------
@@ -1404,7 +1414,9 @@ def transpose(self, *dims) -> "Variable":
14041414
"""
14051415
if len(dims) == 0:
14061416
dims = self.dims[::-1]
1407-
dims = tuple(infix_dims(dims, self.dims))
1417+
else:
1418+
dims = tuple(infix_dims(dims, self.dims, missing_dims))
1419+
14081420
if len(dims) < 2 or dims == self.dims:
14091421
# no need to transpose if only one dimension
14101422
# or dims are in same order

xarray/tests/test_dataset.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -5195,10 +5195,19 @@ def test_dataset_transpose(self):
51955195
expected_dims = tuple(d for d in new_order if d in ds[k].dims)
51965196
assert actual[k].dims == expected_dims
51975197

5198-
with pytest.raises(ValueError, match=r"permuted"):
5199-
ds.transpose("dim1", "dim2", "dim3")
5200-
with pytest.raises(ValueError, match=r"permuted"):
5201-
ds.transpose("dim1", "dim2", "dim3", "time", "extra_dim")
5198+
# test missing dimension, raise error
5199+
with pytest.raises(ValueError):
5200+
ds.transpose(..., "not_a_dim")
5201+
5202+
# test missing dimension, ignore error
5203+
actual = ds.transpose(..., "not_a_dim", missing_dims="ignore")
5204+
expected_ell = ds.transpose(...)
5205+
assert_identical(expected_ell, actual)
5206+
5207+
# test missing dimension, raise warning
5208+
with pytest.warns(UserWarning):
5209+
actual = ds.transpose(..., "not_a_dim", missing_dims="warn")
5210+
assert_identical(expected_ell, actual)
52025211

52035212
assert "T" not in dir(ds)
52045213

xarray/tests/test_variable.py

+14
Original file line numberDiff line numberDiff line change
@@ -1466,6 +1466,20 @@ def test_transpose(self):
14661466
w3 = Variable(["b", "c", "d", "a"], np.einsum("abcd->bcda", x))
14671467
assert_identical(w, w3.transpose("a", "b", "c", "d"))
14681468

1469+
# test missing dimension, raise error
1470+
with pytest.raises(ValueError):
1471+
v.transpose(..., "not_a_dim")
1472+
1473+
# test missing dimension, ignore error
1474+
actual = v.transpose(..., "not_a_dim", missing_dims="ignore")
1475+
expected_ell = v.transpose(...)
1476+
assert_identical(expected_ell, actual)
1477+
1478+
# test missing dimension, raise warning
1479+
with pytest.warns(UserWarning):
1480+
v.transpose(..., "not_a_dim", missing_dims="warn")
1481+
assert_identical(expected_ell, actual)
1482+
14691483
def test_transpose_0d(self):
14701484
for value in [
14711485
3.5,

0 commit comments

Comments
 (0)