I have this situation:
>>> ds
<xarray.Dataset>
Dimensions: (x0: 3, y0: 3, y1: 3)
Coordinates:
* x0 (x0) int64 0 1 2
* y0 (y0) int64 0 1 2
* y1 (y1) int64 0 1 2
Data variables:
da1 (x0, y0) int64 20 30 40 50 60 70 80 90 100
da2 (x0, y1) int64 20 30 40 50 60 70 80 90 100
I know that y0
and y1
are identical, and I do not want y1
to be a part of the dataset. I'd like to drop y1
as a dimension and coordinate, and reassign it to use y0
without losing variables. Does anyone have any tips on the combination of Xarray operators to accomplish this? Thanks!
I can accomplish this in a for loop like this:
for v in ds.data_vars:
if 'y1' in ds[v].coords:
ds[v] = ds[v].swap_dims({'y1':'y0'})
But when I do:
ds.swap_dims({'y1':'y0'})
I get this error:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/dadriaan/.conda/envs/icing/lib/python3.9/site-packages/xarray/core/dataset.py", line 3559, in swap_dims
raise ValueError(
ValueError: replacement dimension 'y0' is not a 1D variable along the old dimension 'y1'
that I don't quite understand.
Hmm that looks like a bug. How about a simple ds.rename_dims({"y1": "y0"})
Deepak Cherian said:
Hmm that looks like a bug. How about a simple
ds.rename_dims({"y1": "y0"})
ValueError: Cannot rename y1 to y0 because y0 already exists. Try using swap_dims instead.
:upside_down:
Also, here is more code for testing:
import xarray as xr
da1 = xr.DataArray([[20,30,40],[50,60,70],[80,90,100]],dims=['x0','y0'],coords={'x0':[0,1,2],'y0':[0,1,2]})
da2 = xr.DataArray([[20,30,40],[50,60,70],[80,90,100]],dims=['x0','y1'],coords={'x0':[0,1,2],'y1':[0,1,2]})
ds = xr.Dataset(data_vars={'da1':da1,'da2':da2})
print(ds)
for v in ds.data_vars:
if 'y1' in ds[v].coords:
ds[v] = ds[v].swap_dims({'y1':'y0'})
print(ds)
#ds.swap_dims({'y1':'y0'})
#ds.rename_dims({"y1": "y0"})
I am using 2022.3.0. I will try it also with 2023.1.0 right now and see what I get.
Oh yeah that might help. 2022.3.0 merged in some major under-the-hood changes, and many bugs have been fixed since then.
Identical behavior:
>>> ds.swap_dims({'y1':'y0'})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/dadriaan/.conda/envs/xrbug/lib/python3.10/site-packages/xarray/core/dataset.py", line 3829, in swap_dims
raise ValueError(
ValueError: replacement dimension 'y0' is not a 1D variable along the old dimension 'y1'
>>> print(xr.__version__)
2023.1.0
>>> ds.rename_dims({'y1':'y0'})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/dadriaan/.conda/envs/xrbug/lib/python3.10/site-packages/xarray/core/dataset.py", line 3707, in rename_dims
raise ValueError(
ValueError: Cannot rename y1 to y0 because y0 already exists. Try using swap_dims instead.
OK, the example code in the documentation returns the same error at this page:
https://docs.xarray.dev/en/stable/generated/xarray.Dataset.swap_dims.html
ds = xr.Dataset(
data_vars={"a": ("x", [5, 7]), "b": ("x", [0.1, 2.4])},
coords={"x": ["a", "b"], "y": ("x", [0, 1])},
)
ds.swap_dims({"x": "y"})
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/home/dadriaan/.conda/envs/xrbug/lib/python3.10/site-packages/xarray/core/dataset.py", line 3833, in swap_dims
raise ValueError(
ValueError: replacement dimension 'y' is not a 1D variable along the old dimension 'x'
I will open an issue over on GitHub.
Scratch that, the copy-paste from the docs caused that issue. If I reformat the creation of ds, it works. I will do some more testing.
del ds["y1"]
ds.rename({"y1": "y0"})
this seems to work
Interesting, that does work.
Also in dataset.py
, it works if I comment out the section of code that causes it to fail:
if v in self.variables and self.variables[v].dims != (k,):
raise ValueError(
f"replacement dimension {v!r} is not a 1D "
f"variable along the old dimension {k!r}"
)
I am struggling to understand what that code ^^^ is doing or what edge case it's designed to catch.
It also works if I choose a random name that doesn't exist in self.variables
, because the second half of the and
in the above code fails:
ds.swap_dims({"y1":"foo"})
<xarray.Dataset>
Dimensions: (x0: 3, y0: 3, foo: 3)
Coordinates:
* x0 (x0) int64 0 1 2
* y0 (y0) int64 0 1 2
y1 (foo) int64 0 1 2
Dimensions without coordinates: foo
Data variables:
da1 (x0, y0) int64 20 30 40 50 60 70 80 90 100
da2 (x0, foo) int64 20 30 40 50 60 70 80 90 100
Last updated: May 16 2025 at 17:14 UTC