Skip to content

Commit 5f2e94d

Browse files
committed
Extract dataarray path into method
1 parent 73e85d2 commit 5f2e94d

1 file changed

Lines changed: 43 additions & 22 deletions

File tree

linopy/common.py

Lines changed: 43 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
147189
def 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

Comments
 (0)