@@ -144,6 +144,48 @@ def _coords_to_mapping(coords: CoordsLike, dims: DimsLike | None = None) -> Mapp
144144 return {c .name : c for c in seq if hasattr (c , "name" ) and c .name }
145145
146146
147+ def _validate_dataarray_coords (
148+ arr : DataArray ,
149+ coords : CoordsLike | None = None ,
150+ dims : DimsLike | None = None ,
151+ allow_extra_dims : bool = False ,
152+ ) -> DataArray :
153+ """
154+ Validate a DataArray's coordinates against expected coords.
155+
156+ For shared dimensions, coordinates must match exactly. Extra
157+ dimensions in the DataArray raise unless allow_extra_dims is True.
158+ Missing dimensions are broadcast via expand_dims.
159+ """
160+ if coords is None :
161+ return arr
162+
163+ expected = _coords_to_mapping (coords , dims )
164+ if not expected :
165+ return arr
166+
167+ if not allow_extra_dims :
168+ extra = set (arr .dims ) - set (expected )
169+ if extra :
170+ raise ValueError (f"DataArray has extra dimensions not in coords: { extra } " )
171+
172+ for k , v in expected .items ():
173+ if k in arr .dims :
174+ expected_idx = pd .Index (v )
175+ actual_idx = pd .Index (arr .coords [k ].values )
176+ if not actual_idx .equals (expected_idx ):
177+ raise ValueError (
178+ f"Coordinates for dimension '{ k } ' do not match: "
179+ f"expected { expected_idx .tolist ()} , got { actual_idx .tolist ()} "
180+ )
181+
182+ expand = {k : v for k , v in expected .items () if k not in arr .dims }
183+ if expand :
184+ arr = arr .expand_dims (expand )
185+
186+ return arr
187+
188+
147189def pandas_to_dataarray (
148190 arr : pd .DataFrame | pd .Series ,
149191 coords : CoordsLike | None = None ,
@@ -295,28 +337,7 @@ def as_dataarray(
295337 elif isinstance (arr , int | float | str | bool | list ):
296338 arr = DataArray (arr , coords = coords , dims = dims , ** kwargs )
297339 elif isinstance (arr , DataArray ):
298- if coords is not None :
299- coords = _coords_to_mapping (coords , dims )
300- if coords is not None and isinstance (coords , Mapping ):
301- if not allow_extra_dims :
302- extra_dims = set (arr .dims ) - set (coords )
303- if extra_dims :
304- raise ValueError (
305- f"DataArray has extra dimensions not in coords: { extra_dims } "
306- )
307- for k , v in coords .items ():
308- if k in arr .dims :
309- expected = pd .Index (v )
310- actual = pd .Index (arr .coords [k ].values )
311- if not actual .equals (expected ):
312- raise ValueError (
313- f"Coordinates for dimension '{ k } ' do not match: "
314- f"expected { expected .tolist ()} , got { actual .tolist ()} "
315- )
316- # Expand to new dimensions from coords (broadcast)
317- expand_coords = {k : v for k , v in coords .items () if k not in arr .dims }
318- if expand_coords :
319- arr = arr .expand_dims (expand_coords )
340+ arr = _validate_dataarray_coords (arr , coords , dims , allow_extra_dims )
320341 elif not isinstance (arr , DataArray ):
321342 supported_types = [
322343 np .number ,
0 commit comments