Skip to content

Fix quantile raising on an empty result - #11553

Open
chiruu12 wants to merge 6 commits into
pydata:mainfrom
chiruu12:fix/11549-quantile-empty-dim
Open

Fix quantile raising on an empty result#11553
chiruu12 wants to merge 6 commits into
pydata:mainfrom
chiruu12:fix/11549-quantile-empty-dim

Conversation

@chiruu12

@chiruu12 chiruu12 commented Sep 1, 2026

Copy link
Copy Markdown

Closes #11549.

_wrapper builds the empty result itself instead of moving a q axis that is not there. Both backing functions are unusable on this input: np.nanquantile returns the nan but drops the leading q axis, so moveaxis hands apply_ufunc the wrong rank, and np.quantile raises before returning anything.

The trigger is npa.size == 0, not an empty reduced axis. DataArray(zeros((0, 3))).quantile(0.5, dim="y") reduces over y, which has length 3, and is still empty because x is.

before after
empty.quantile(0.5) AxisError nan
empty.quantile(0.5, skipna=False) IndexError nan
zeros((0,3)).quantile(0.5, dim="y") ValueError shape (0,)
empty datetime64 / timedelta64 IndexError NaT, dtype kept

Datetimes keep their own dtype and NA. That matches the non-empty path, median, and groupby_bins(...).quantile() over an empty bin. Returning float64 nan instead made concat of an empty and a non-empty result fail to promote.

Empty input is validated exactly as non-empty input is, by running the call over one element first so numpy owns the message. Without that, q=1.5 raised on a 5-element array and returned nan on a 0-element one.

skipna=False returns nan too, so both paths agree. That differs from numpy, where np.quantile([], 0.5) raises, but it is what median(skipna=False) and mean(skipna=False) already do on an empty dimension.

Known gap: a pandas extension dtype the non-empty path rejects (string, category, interval, period, boolean) is still accepted when empty, as it already is for object arrays. numpy cannot build a probe array from those dtypes, so only q and method are checked there.

Tests at Variable, DataArray and Dataset level cover the empty reduction, the empty-but-not-reduced dimension, datetime dtype retention, extension dtypes, and the argument validation. Against origin/main, 24 fail and 3 pass; the 3 are guards, two of them against a regression this PR introduced and then fixed.

test_variable, test_dataarray, test_dataset, test_groupby, test_weighted, test_computation, test_duck_array_ops, test_units, test_concat: 2961 passed. ruff check and format clean.

I could not exercise the dask path; dask is not installed in my environment.

Copilot AI lite review requested due to automatic review settings September 1, 2026 05:52

Copilot AI 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.

🟡 Changes recommended

The new datetime/timedelta empty-result behavior can conflict with dask gufunc metadata because output_dtypes is still hard-coded to float64, which can break chunked execution.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Fixes quantile on empty results so it returns missing values (rather than raising) and preserves datetime/timedelta dtype semantics, aligning behavior with other reductions and pandas.

Changes:

  • Add an empty-result fast path to Variable.quantile() that validates arguments and returns correctly shaped fill values (NaN / NaT).
  • Add targeted tests for empty inputs across Variable, DataArray, and Dataset quantile reductions.
  • Document the behavior change in the “Bug Fixes” section of the release notes.
File summaries
File Description
xarray/core/variable.py Implements the empty-result handling in Variable.quantile() and preserves datetime/timedelta NA semantics.
xarray/tests/test_variable.py Adds comprehensive tests for empty-quantile behavior, argument validation, dtype retention, and extension dtypes.
xarray/tests/test_dataarray.py Adds a DataArray.quantile() regression test for empty inputs.
xarray/tests/test_dataset.py Adds a Dataset.quantile() regression test for empty inputs.
doc/whats-new.rst Notes the bug fix and the new empty-result behavior in release notes.
Review details
  • Files reviewed: 5/5 changed files
  • Comments generated: 1
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread xarray/core/variable.py
Comment on lines +2082 to +2086
if npa.dtype.kind in "mM":
fill_value = np.array("NaT", dtype=npa.dtype)
result_dtype = npa.dtype
else:
fill_value = np.nan
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

quantile fails on an empty dimension where other reductions return NaN

2 participants