xarray icon indicating copy to clipboard operation
xarray copied to clipboard

raise an error for `assign_coords({Hashable: xr.Coordinates})`

Open dcherian opened this issue 8 months ago • 2 comments

What happened?

This works but is wrong.

import xarray as xr
from xarray.indexes import RangeIndex

ds = xr.Dataset({"foo": ("x", [1, 2, 3])})
coords = xr.Coordinates.from_xindex(RangeIndex.arange("x", "x", 1.5, 4.5, 1.0))
ds.assign_coords({"x": coords})

What did you expect to happen?

We should error and tell the user to use ds.assign_coords(coords) instead

xref https://github.com/pydata/xarray/pull/10076/commits/efe3e81be686881ca63a561095e95f50856a8d19#r2019841034

dcherian avatar Mar 31 '25 14:03 dcherian

Yes I agree we can easily detect when such case happens.

benbovy avatar Apr 03 '25 00:04 benbovy

Running this on main now raises:

In [1]: import xarray as xr
   ...: from xarray.indexes import RangeIndex
   ...:
   ...: ds = xr.Dataset({"foo": ("x", [1, 2, 3])})
   ...: coords = xr.Coordinates.from_xindex(RangeIndex.arange(1.5, 4.5, 1.0, dim='x', coord_name='x'))

In [2]: ds.assign_coords({"x": coords})
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
Cell In[2], line 1
----> 1 ds.assign_coords({"x": coords})

File ~/repositories/xarray/xarray/core/common.py:664, in DataWithCoords.assign_coords(self, coords, **coords_kwargs)
    661 else:
    662     results = self._calc_assign_results(coords_combined)
--> 664 data.coords.update(results)
    665 return data

File ~/repositories/xarray/xarray/core/coordinates.py:603, in Coordinates.update(self, other)
    597 # special case for PandasMultiIndex: updating only its dimension coordinate
    598 # is still allowed but depreciated.
    599 # It is the only case where we need to actually drop coordinates here (multi-index levels)
    600 # TODO: remove when removing PandasMultiIndex's dimension coordinate.
    601 self._drop_coords(self._names - coords_to_align._names)
--> 603 self._update_coords(coords, indexes)

File ~/repositories/xarray/xarray/core/coordinates.py:789, in DatasetCoordinates._update_coords(self, coords, indexes)
    786 variables.update(coords)
    788 # check for inconsistent state *before* modifying anything in-place
--> 789 dims = calculate_dimensions(variables)
    790 new_coord_names = set(coords)
    791 for dim in dims.keys():

File ~/repositories/xarray/xarray/core/variable.py:3031, in calculate_dimensions(variables)
   3029             last_used[dim] = k
   3030         elif dims[dim] != size:
-> 3031             raise ValueError(
   3032                 f"conflicting sizes for dimension {dim!r}: "
   3033                 f"length {size} on {k!r} and length {dims[dim]} on {last_used!r}"
   3034             )
   3035 return dims

ValueError: conflicting sizes for dimension 'x': length 1 on 'x' and length 3 on {'x': 'foo'}

gcaria avatar May 13 '25 19:05 gcaria