Skip to content

Commit 5489eff

Browse files
committed
Accept missing_dims for Variable.tranpose and Dataset.transpose
1 parent 8090513 commit 5489eff

File tree

4 files changed

+56
-13
lines changed

4 files changed

+56
-13
lines changed

xarray/core/dataset.py

Lines changed: 15 additions & 7 deletions
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

Lines changed: 14 additions & 2 deletions
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

Lines changed: 13 additions & 4 deletions
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

Lines changed: 14 additions & 0 deletions
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)