Skip to content

Use flox for median in groupby/resample operations - #11239

Merged
dcherian merged 13 commits into
pydata:mainfrom
sdiebolt:median-flox
Aug 13, 2026
Merged

dcherian merged 13 commits into
pydata:mainfrom
sdiebolt:median-flox

Conversation

@sdiebolt

Copy link
Copy Markdown
Contributor

Add flox support to median() methods in:

  • DataArrayGroupByAggregations
  • DatasetGroupByAggregations
  • DataArrayResampleAggregations
  • DatasetResampleAggregations

This aligns the implementation with the documentation which already claimed flox was used when available. The fix provides significant performance improvements when flox can process the data. A fallback to the non-flox implementation is included for cases where flox's median aggregation requires blockwise processing but the data chunking doesn't support it.

Closes #11238

  • User visible changes (including notable bug fixes) are documented in whats-new.rst

Add flox support to median() methods in:
- DataArrayGroupByAggregations
- DatasetGroupByAggregations
- DataArrayResampleAggregations
- DatasetResampleAggregations

This aligns the implementation with the documentation which already
claimed flox was used when available. The fix provides significant
performance improvements when flox can process the data. A fallback to
the non-flox implementation is included for cases where flox's median
aggregation requires blockwise processing but the data chunking doesn't
support it.

Closes pydata#11238

@dcherian dcherian left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for taking this on!

Let's raise FutureWarning here asking the user to shuffle_to_chunks or rechunk appropriately and that this behaviour will be deprecated in 6 months (please open an issue for that). Now that I think about it; we can do this in flox automatically: xarray-contrib/flox#501

The reason I hadn't done this so far is that dask will do some auto-rechunking to make it work; and so some workloads will break.

Also this file is generated by generate_aggregations.py. Please make the edit there instead

@themavik themavik left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this could break silently if flox rewords the ValueError for non-blockwise median; fallback keys off an exact substring.

@sdiebolt

Copy link
Copy Markdown
Contributor Author

The reason I hadn't done this so far is that dask will do some auto-rechunking to make it work; and so some workloads will break.

Also this file is generated by generate_aggregations.py. Please make the edit there instead

Will dot! Should I also run generate_aggregations.py and commit the generated output? It seems to change a lot of things in the generated docstrings that don't have much to do with my changes.

@dcherian

Copy link
Copy Markdown
Contributor

Should I also run generate_aggregations.py and commit the generated output?

Yes, and hmmm.... the output shouldn't chnage that much.

…kwise"

Edit generate_aggregations.py instead of the generated _aggregations.py file
and pass method="blockwise" to flox, which lets flox automatically rechunk
1-D groupers so the call works regardless of input chunking. The previous
try/except fallback keyed on a flox error message substring, which could
break silently if flox ever reworded that error.
@github-actions github-actions Bot added topic-NamedArray Lightweight version of Variable CI Continuous Integration tools labels Aug 12, 2026
@sdiebolt
sdiebolt force-pushed the median-flox branch 2 times, most recently from 0ebee6f to 71b4b96 Compare August 12, 2026 11:03
@github-actions github-actions Bot added topic-backends topic-indexing topic-groupby topic-dask topic-plotting topic-testing topic-performance topic-cftime topic-zarr Related to zarr storage library topic-arrays related to flexible array support topic-rolling Automation Github bots, testing workflows, release automation topic-DataTree Related to the implementation of a DataTree class topic-typing topic-hypothesis Strategies or tests using the hypothesis library io labels Aug 12, 2026
Resolves merge conflicts in:
- xarray/util/generate_aggregations.py: combine flox_call_kwargs (median
  dispatch) with upstream's aggregation_type/long_name support
- xarray/core/_aggregations.py: regenerate via the merged generator
After regenerating _aggregations.py files with the merged generator,
the doctest expectations no longer matched the actual output. Running
pytest with --accept updated the docstrings to include the expected
output so the doctests pass.
pre-commit-ci Bot and others added 4 commits August 12, 2026 11:06
During the merge of upstream/main into median-flox, the
method_is_not_flox_supported tuple in generate_aggregations.py ended up as
("cumsum", "cumprod"). That meant cumsum fell through to the non-flox path
and broke under dask + lazy groupby (macos-latest | test-py314 and
ubuntu-latest | test-py314-no-numba). It also kept median in the list,
defeating the goal of this PR.

The correct tuple is just ("cumprod",) since flox doesn't implement it,
but does implement median (this PR) and cumsum (since flox 0.10.5).

Regenerated core/_aggregations.py via the merged generator and ran
pytest --doctest-modules --accept to update docstrings.
The previous fix used method.name in ("cumprod",) which ruff flagged as a
membership test against a single-item container. Use a direct equality
check instead.

Regenerated core/_aggregations.py.
@sdiebolt

Copy link
Copy Markdown
Contributor Author

Finally found time to come back to this PR, sorry for the delay! It should be good to review again. I may have broken the labels bot by force-pushing somehow, sorry about that!

@sdiebolt
sdiebolt requested a review from dcherian August 12, 2026 14:05
Use kwargs.setdefault so callers can still override flox method while median defaults to blockwise.

@dcherian dcherian left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@dcherian
dcherian merged commit 7c008c3 into pydata:main Aug 13, 2026
43 of 44 checks passed
TomNicholas added a commit that referenced this pull request Sep 29, 2026
* Update whats-new for v2026.09.0 release

- Rename the unreleased section to v2026.09.0 and add the release summary
  and contributor list
- Move entries for #11348, #11292, #11290 and #11239 that were merged into
  older release sections
- Add missing entries for #11552, #11521, #11486 and #11513
- Add missing PR links, fix the #11547 link and other markup
- Fix the documented default of the use_bottleneck option
- Add contributor names to the typos allow-list

* Mention plot.lines and last Python 3.11 release in whats-new
headtr1ck added a commit to headtr1ck/xarray that referenced this pull request Oct 1, 2026
Since pydata#11239, groupby median on dask arrays uses flox with
method="blockwise". flox can only rechunk so that chunk boundaries line
up with group boundaries if the members of each group are contiguous.
With interleaved labels spread over multiple chunks this raised an
InvalidIndexError. Shuffle every group into a single chunk first.

This can be restricted to older flox versions once
xarray-contrib/flox#501 is fixed.

Fixes pydata#11651

Co-authored-by: Claude <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Automation Github bots, testing workflows, release automation CI Continuous Integration tools io topic-arrays related to flexible array support topic-backends topic-cftime topic-dask topic-DataTree Related to the implementation of a DataTree class topic-groupby topic-hypothesis Strategies or tests using the hypothesis library topic-indexing topic-NamedArray Lightweight version of Variable topic-performance topic-plotting topic-rolling topic-testing topic-typing topic-zarr Related to zarr storage library

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Use flox for median-aggregation in groupbys

3 participants