@@ -257,8 +257,6 @@ def xarray_reduce(
257
257
more_drop .update (idx_other_names )
258
258
maybe_drop .update (more_drop )
259
259
260
- ds = ds .drop_vars ([var for var in maybe_drop if var in ds .variables ])
261
-
262
260
if dim is Ellipsis :
263
261
if nby > 1 :
264
262
raise NotImplementedError ("Multiple by are not allowed when dim is Ellipsis." )
@@ -275,17 +273,23 @@ def xarray_reduce(
275
273
# broadcast to make sure grouper dimensions are present in the array.
276
274
exclude_dims = tuple (d for d in ds .dims if d not in grouper_dims and d not in dim_tuple )
277
275
276
+ if any (d not in grouper_dims and d not in obj .dims for d in dim_tuple ):
277
+ raise ValueError (f"Cannot reduce over absent dimensions { dim } ." )
278
+
278
279
try :
279
280
xr .align (ds , * by_da , join = "exact" , copy = False )
280
281
except ValueError as e :
281
282
raise ValueError (
282
283
"Object being grouped must be exactly aligned with every array in `by`."
283
284
) from e
284
285
285
- ds_broad = xr .broadcast (ds , * by_da , exclude = exclude_dims )[0 ]
286
-
287
- if any (d not in grouper_dims and d not in obj .dims for d in dim_tuple ):
288
- raise ValueError (f"Cannot reduce over absent dimensions { dim } ." )
286
+ needs_broadcast = any (
287
+ not set (grouper_dims ).issubset (set (variable .dims )) for variable in ds .data_vars .values ()
288
+ )
289
+ if needs_broadcast :
290
+ ds_broad = xr .broadcast (ds , * by_da , exclude = exclude_dims )[0 ]
291
+ else :
292
+ ds_broad = ds
289
293
290
294
dims_not_in_groupers = tuple (d for d in dim_tuple if d not in grouper_dims )
291
295
if dims_not_in_groupers == tuple (dim_tuple ) and not any (isbins ):
@@ -305,6 +309,8 @@ def xarray_reduce(
305
309
else :
306
310
return result
307
311
312
+ ds = ds .drop_vars ([var for var in maybe_drop if var in ds .variables ])
313
+
308
314
axis = tuple (range (- len (dim_tuple ), 0 ))
309
315
310
316
# Set expected_groups and convert to index since we need coords, sizes
@@ -432,7 +438,7 @@ def wrapper(array, *by, func, skipna, core_dims, **kwargs):
432
438
433
439
# restore non-dim coord variables without the core dimension
434
440
# TODO: shouldn't apply_ufunc handle this?
435
- for var in set (ds_broad .variables ) - set (ds_broad ._indexes ) - set (ds_broad .dims ):
441
+ for var in set (ds_broad ._coord_names ) - set (ds_broad ._indexes ) - set (ds_broad .dims ):
436
442
if all (d not in ds_broad [var ].dims for d in dim_tuple ):
437
443
actual [var ] = ds_broad [var ]
438
444
0 commit comments