Skip to content
Open
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions doc/whats-new.rst
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ Internal Changes
runtime behavior. This enables CI integration for type stub validation and helps
prevent type annotation regressions (:issue:`11086`).
By `Kristian Kollsgård <https://github.com/kkollsga>`_.
- Add flox support for :py:meth:`DataArray.groupby().median`,
:py:meth:`Dataset.groupby().median`, :py:meth:`DataArray.resample().median`, and
:py:meth:`Dataset.resample().median`. This significantly speeds up median reductions
when flox is installed and the data chunking allows blockwise processing. For
incompatible chunking, a fallback to the non-flox implementation ensures backward
compatibility. (:issue:`11238`, :pull:`11239`). By `Samuel Le Meur-Diebolt
<https://github.com/sdiebolt>`_.


.. _whats-new.2026.02.0:

Expand Down
86 changes: 86 additions & 0 deletions xarray/core/_aggregations.py
Original file line number Diff line number Diff line change
Expand Up @@ -4911,6 +4911,28 @@ def median(
Data variables:
da (labels) float64 24B nan 2.0 1.5
"""
if (
flox_available
and OPTIONS["use_flox"]
and contains_only_chunked_or_numpy(self._obj)
):
try:
return self._flox_reduce(
func="median",
dim=dim,
skipna=skipna,
numeric_only=True,
# fill_value=fill_value,
keep_attrs=keep_attrs,
**kwargs,
)
except ValueError as e:
if "median is only supported for `method='blockwise'`" in str(e):
# Fall back to non-flox implementation when chunking doesn't
# allow blockwise processing
pass
else:
raise
return self.reduce(
duck_array_ops.median,
dim=dim,
Expand Down Expand Up @@ -6407,6 +6429,28 @@ def median(
Data variables:
da (time) float64 24B 1.0 2.0 nan
"""
if (
flox_available
and OPTIONS["use_flox"]
and contains_only_chunked_or_numpy(self._obj)
):
try:
return self._flox_reduce(
func="median",
dim=dim,
skipna=skipna,
numeric_only=True,
# fill_value=fill_value,
keep_attrs=keep_attrs,
**kwargs,
)
except ValueError as e:
if "median is only supported for `method='blockwise'`" in str(e):
# Fall back to non-flox implementation when chunking doesn't
# allow blockwise processing
pass
else:
raise
return self.reduce(
duck_array_ops.median,
dim=dim,
Expand Down Expand Up @@ -7804,6 +7848,27 @@ def median(
Coordinates:
* labels (labels) object 24B 'a' 'b' 'c'
"""
if (
flox_available
and OPTIONS["use_flox"]
and contains_only_chunked_or_numpy(self._obj)
):
try:
return self._flox_reduce(
func="median",
dim=dim,
skipna=skipna,
# fill_value=fill_value,
keep_attrs=keep_attrs,
**kwargs,
)
except ValueError as e:
if "median is only supported for `method='blockwise'`" in str(e):
# Fall back to non-flox implementation when chunking doesn't
# allow blockwise processing
pass
else:
raise
return self.reduce(
duck_array_ops.median,
dim=dim,
Expand Down Expand Up @@ -9192,6 +9257,27 @@ def median(
Coordinates:
* time (time) datetime64[us] 24B 2001-01-31 2001-04-30 2001-07-31
"""
if (
flox_available
and OPTIONS["use_flox"]
and contains_only_chunked_or_numpy(self._obj)
):
try:
return self._flox_reduce(
func="median",
dim=dim,
skipna=skipna,
# fill_value=fill_value,
keep_attrs=keep_attrs,
**kwargs,
)
except ValueError as e:
if "median is only supported for `method='blockwise'`" in str(e):
# Fall back to non-flox implementation when chunking doesn't allow
# blockwise processing.
pass
else:
raise
return self.reduce(
duck_array_ops.median,
dim=dim,
Expand Down
Loading