Skip to content
Open
Show file tree
Hide file tree
Changes from all 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