diff --git a/xarray/core/_reductions.py b/xarray/core/_reductions.py index d2aebd3efa7..d0c2a9d721d 100644 --- a/xarray/core/_reductions.py +++ b/xarray/core/_reductions.py @@ -3,10 +3,11 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Hashable, Sequence +from typing import TYPE_CHECKING, Any, Callable, Sequence from . import duck_array_ops from .options import OPTIONS +from .types import Dims from .utils import contains_only_dask_or_numpy if TYPE_CHECKING: @@ -25,9 +26,9 @@ class DatasetReductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, - axis: None | int | Sequence[int] = None, + axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, **kwargs: Any, @@ -36,7 +37,7 @@ def reduce( def count( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -46,7 +47,7 @@ def count( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``count``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. keep_attrs : bool or None, optional @@ -108,7 +109,7 @@ def count( def all( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -118,7 +119,7 @@ def all( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``all``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. keep_attrs : bool or None, optional @@ -180,7 +181,7 @@ def all( def any( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -190,7 +191,7 @@ def any( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``any``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. keep_attrs : bool or None, optional @@ -252,7 +253,7 @@ def any( def max( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -263,7 +264,7 @@ def max( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``max``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -339,7 +340,7 @@ def max( def min( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -350,7 +351,7 @@ def min( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``min``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -426,7 +427,7 @@ def min( def mean( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -437,7 +438,7 @@ def mean( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``mean``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -517,7 +518,7 @@ def mean( def prod( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -529,7 +530,7 @@ def prod( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``prod``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -624,7 +625,7 @@ def prod( def sum( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -636,7 +637,7 @@ def sum( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``sum``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -731,7 +732,7 @@ def sum( def std( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, ddof: int = 0, @@ -743,7 +744,7 @@ def std( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``std``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -835,7 +836,7 @@ def std( def var( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, ddof: int = 0, @@ -847,7 +848,7 @@ def var( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``var``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -939,7 +940,7 @@ def var( def median( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -950,7 +951,7 @@ def median( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``median``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -1035,9 +1036,9 @@ class DataArrayReductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, - axis: None | int | Sequence[int] = None, + axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, **kwargs: Any, @@ -1046,7 +1047,7 @@ def reduce( def count( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -1056,7 +1057,7 @@ def count( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``count``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. keep_attrs : bool or None, optional @@ -1112,7 +1113,7 @@ def count( def all( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -1122,7 +1123,7 @@ def all( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``all``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. keep_attrs : bool or None, optional @@ -1178,7 +1179,7 @@ def all( def any( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -1188,7 +1189,7 @@ def any( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``any``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. keep_attrs : bool or None, optional @@ -1244,7 +1245,7 @@ def any( def max( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1255,7 +1256,7 @@ def max( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``max``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -1323,7 +1324,7 @@ def max( def min( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1334,7 +1335,7 @@ def min( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``min``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -1402,7 +1403,7 @@ def min( def mean( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1413,7 +1414,7 @@ def mean( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``mean``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -1485,7 +1486,7 @@ def mean( def prod( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -1497,7 +1498,7 @@ def prod( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``prod``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -1582,7 +1583,7 @@ def prod( def sum( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -1594,7 +1595,7 @@ def sum( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``sum``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -1679,7 +1680,7 @@ def sum( def std( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, ddof: int = 0, @@ -1691,7 +1692,7 @@ def std( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``std``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -1773,7 +1774,7 @@ def std( def var( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, ddof: int = 0, @@ -1785,7 +1786,7 @@ def var( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``var``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -1867,7 +1868,7 @@ def var( def median( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1878,7 +1879,7 @@ def median( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``median``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions. skipna : bool or None, optional @@ -1955,9 +1956,9 @@ class DatasetGroupByReductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, - axis: None | int | Sequence[int] = None, + axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, **kwargs: Any, @@ -1966,14 +1967,14 @@ def reduce( def _flox_reduce( self, - dim: None | Hashable | Sequence[Hashable], + dim: Dims | ellipsis, **kwargs: Any, ) -> Dataset: raise NotImplementedError() def count( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -1983,9 +1984,10 @@ def count( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``count``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. keep_attrs : bool or None, optional If True, ``attrs`` will be copied from the original object to the new one. If False, the new object will be @@ -2057,7 +2059,7 @@ def count( def all( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -2067,9 +2069,10 @@ def all( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``all``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. keep_attrs : bool or None, optional If True, ``attrs`` will be copied from the original object to the new one. If False, the new object will be @@ -2141,7 +2144,7 @@ def all( def any( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -2151,9 +2154,10 @@ def any( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``any``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. keep_attrs : bool or None, optional If True, ``attrs`` will be copied from the original object to the new one. If False, the new object will be @@ -2225,7 +2229,7 @@ def any( def max( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -2236,9 +2240,10 @@ def max( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``max``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -2327,7 +2332,7 @@ def max( def min( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -2338,9 +2343,10 @@ def min( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``min``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -2429,7 +2435,7 @@ def min( def mean( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -2440,9 +2446,10 @@ def mean( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``mean``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -2535,7 +2542,7 @@ def mean( def prod( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -2547,9 +2554,10 @@ def prod( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``prod``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -2660,7 +2668,7 @@ def prod( def sum( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -2672,9 +2680,10 @@ def sum( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``sum``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -2785,7 +2794,7 @@ def sum( def std( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -2797,9 +2806,10 @@ def std( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``std``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -2907,7 +2917,7 @@ def std( def var( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -2919,9 +2929,10 @@ def var( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``var``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -3029,7 +3040,7 @@ def var( def median( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3040,9 +3051,10 @@ def median( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``median``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -3129,9 +3141,9 @@ class DatasetResampleReductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, - axis: None | int | Sequence[int] = None, + axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, **kwargs: Any, @@ -3140,14 +3152,14 @@ def reduce( def _flox_reduce( self, - dim: None | Hashable | Sequence[Hashable], + dim: Dims | ellipsis, **kwargs: Any, ) -> Dataset: raise NotImplementedError() def count( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -3157,9 +3169,10 @@ def count( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``count``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. keep_attrs : bool or None, optional If True, ``attrs`` will be copied from the original object to the new one. If False, the new object will be @@ -3231,7 +3244,7 @@ def count( def all( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -3241,9 +3254,10 @@ def all( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``all``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. keep_attrs : bool or None, optional If True, ``attrs`` will be copied from the original object to the new one. If False, the new object will be @@ -3315,7 +3329,7 @@ def all( def any( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -3325,9 +3339,10 @@ def any( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``any``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. keep_attrs : bool or None, optional If True, ``attrs`` will be copied from the original object to the new one. If False, the new object will be @@ -3399,7 +3414,7 @@ def any( def max( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3410,9 +3425,10 @@ def max( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``max``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -3501,7 +3517,7 @@ def max( def min( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3512,9 +3528,10 @@ def min( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``min``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -3603,7 +3620,7 @@ def min( def mean( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3614,9 +3631,10 @@ def mean( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``mean``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -3709,7 +3727,7 @@ def mean( def prod( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -3721,9 +3739,10 @@ def prod( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``prod``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -3834,7 +3853,7 @@ def prod( def sum( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -3846,9 +3865,10 @@ def sum( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``sum``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -3959,7 +3979,7 @@ def sum( def std( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -3971,9 +3991,10 @@ def std( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``std``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -4081,7 +4102,7 @@ def std( def var( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -4093,9 +4114,10 @@ def var( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``var``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -4203,7 +4225,7 @@ def var( def median( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4214,9 +4236,10 @@ def median( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``median``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -4303,9 +4326,9 @@ class DataArrayGroupByReductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, - axis: None | int | Sequence[int] = None, + axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, **kwargs: Any, @@ -4314,14 +4337,14 @@ def reduce( def _flox_reduce( self, - dim: None | Hashable | Sequence[Hashable], + dim: Dims | ellipsis, **kwargs: Any, ) -> DataArray: raise NotImplementedError() def count( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -4331,9 +4354,10 @@ def count( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``count``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. keep_attrs : bool or None, optional If True, ``attrs`` will be copied from the original object to the new one. If False, the new object will be @@ -4398,7 +4422,7 @@ def count( def all( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -4408,9 +4432,10 @@ def all( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``all``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. keep_attrs : bool or None, optional If True, ``attrs`` will be copied from the original object to the new one. If False, the new object will be @@ -4475,7 +4500,7 @@ def all( def any( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -4485,9 +4510,10 @@ def any( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``any``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. keep_attrs : bool or None, optional If True, ``attrs`` will be copied from the original object to the new one. If False, the new object will be @@ -4552,7 +4578,7 @@ def any( def max( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4563,9 +4589,10 @@ def max( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``max``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -4645,7 +4672,7 @@ def max( def min( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4656,9 +4683,10 @@ def min( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``min``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -4738,7 +4766,7 @@ def min( def mean( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4749,9 +4777,10 @@ def mean( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``mean``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -4835,7 +4864,7 @@ def mean( def prod( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -4847,9 +4876,10 @@ def prod( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``prod``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -4949,7 +4979,7 @@ def prod( def sum( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -4961,9 +4991,10 @@ def sum( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``sum``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -5063,7 +5094,7 @@ def sum( def std( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -5075,9 +5106,10 @@ def std( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``std``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -5174,7 +5206,7 @@ def std( def var( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -5186,9 +5218,10 @@ def var( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``var``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -5285,7 +5318,7 @@ def var( def median( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5296,9 +5329,10 @@ def median( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``median``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the GroupBy dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -5377,9 +5411,9 @@ class DataArrayResampleReductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, - axis: None | int | Sequence[int] = None, + axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, **kwargs: Any, @@ -5388,14 +5422,14 @@ def reduce( def _flox_reduce( self, - dim: None | Hashable | Sequence[Hashable], + dim: Dims | ellipsis, **kwargs: Any, ) -> DataArray: raise NotImplementedError() def count( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -5405,9 +5439,10 @@ def count( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``count``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. keep_attrs : bool or None, optional If True, ``attrs`` will be copied from the original object to the new one. If False, the new object will be @@ -5472,7 +5507,7 @@ def count( def all( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -5482,9 +5517,10 @@ def all( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``all``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. keep_attrs : bool or None, optional If True, ``attrs`` will be copied from the original object to the new one. If False, the new object will be @@ -5549,7 +5585,7 @@ def all( def any( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -5559,9 +5595,10 @@ def any( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``any``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. keep_attrs : bool or None, optional If True, ``attrs`` will be copied from the original object to the new one. If False, the new object will be @@ -5626,7 +5663,7 @@ def any( def max( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5637,9 +5674,10 @@ def max( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``max``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -5719,7 +5757,7 @@ def max( def min( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5730,9 +5768,10 @@ def min( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``min``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -5812,7 +5851,7 @@ def min( def mean( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5823,9 +5862,10 @@ def mean( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``mean``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -5909,7 +5949,7 @@ def mean( def prod( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -5921,9 +5961,10 @@ def prod( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``prod``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -6023,7 +6064,7 @@ def prod( def sum( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -6035,9 +6076,10 @@ def sum( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``sum``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -6137,7 +6179,7 @@ def sum( def std( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -6149,9 +6191,10 @@ def std( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``std``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -6248,7 +6291,7 @@ def std( def var( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -6260,9 +6303,10 @@ def var( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``var``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -6359,7 +6403,7 @@ def var( def median( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -6370,9 +6414,10 @@ def median( Parameters ---------- - dim : hashable or iterable of hashable, default: None + dim : str, Iterable of Hashable, "..." or None, default: None Name of dimension[s] along which to apply ``median``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If None, will reduce over all dimensions. + or ``dim=["x", "y"]``. If None, will reduce over the Resample dimensions. + If "...", will reduce over all dimensions. skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not diff --git a/xarray/core/computation.py b/xarray/core/computation.py index 7d95b9bf373..6ec38453a4b 100644 --- a/xarray/core/computation.py +++ b/xarray/core/computation.py @@ -40,7 +40,7 @@ from .coordinates import Coordinates from .dataarray import DataArray from .dataset import Dataset - from .types import CombineAttrsOptions, Ellipsis, JoinOptions + from .types import CombineAttrsOptions, JoinOptions _NO_FILL_VALUE = utils.ReprObject("") _DEFAULT_NAME = utils.ReprObject("") @@ -1624,7 +1624,7 @@ def cross( def dot( *arrays, - dims: str | Iterable[Hashable] | Ellipsis | None = None, + dims: str | Iterable[Hashable] | ellipsis | None = None, **kwargs: Any, ): """Generalized dot product for xarray objects. Like np.einsum, but diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index 302562243b2..c08a30263b4 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -78,7 +78,7 @@ from .types import ( CoarsenBoundaryOptions, DatetimeUnitOptions, - Ellipsis, + Dims, ErrorOptions, ErrorOptionsWithWarn, InterpOptions, @@ -869,7 +869,7 @@ def coords(self) -> DataArrayCoordinates: @overload def reset_coords( self: T_DataArray, - names: Hashable | Iterable[Hashable] | None = None, + names: Dims = None, drop: Literal[False] = False, ) -> Dataset: ... @@ -877,7 +877,7 @@ def reset_coords( @overload def reset_coords( self: T_DataArray, - names: Hashable | Iterable[Hashable] | None = None, + names: Dims = None, *, drop: Literal[True], ) -> T_DataArray: @@ -885,14 +885,14 @@ def reset_coords( def reset_coords( self: T_DataArray, - names: Hashable | Iterable[Hashable] | None = None, + names: Dims = None, drop: bool = False, ) -> T_DataArray | Dataset: """Given names of coordinates, reset them to become variables. Parameters ---------- - names : Hashable or iterable of Hashable, optional + names : str, Iterable of Hashable or None, optional Name(s) of non-index coordinates in this dataset to reset into variables. By default, all non-index coordinates are reset. drop : bool, default: False @@ -2352,7 +2352,7 @@ def stack( # https://github.com/python/mypy/issues/12846 is resolved def unstack( self, - dim: Hashable | Sequence[Hashable] | None = None, + dim: Dims = None, fill_value: Any = dtypes.NA, sparse: bool = False, ) -> DataArray: @@ -2364,7 +2364,7 @@ def unstack( Parameters ---------- - dim : Hashable or sequence of Hashable, optional + dim : str, Iterable of Hashable or None, optional Dimension(s) over which to unstack. By default unstacks all MultiIndexes. fill_value : scalar or dict-like, default: nan @@ -2888,9 +2888,9 @@ def combine_first(self: T_DataArray, other: T_DataArray) -> T_DataArray: def reduce( self: T_DataArray, func: Callable[..., Any], - dim: None | Hashable | Iterable[Hashable] = None, + dim: Dims | ellipsis = None, *, - axis: None | int | Sequence[int] = None, + axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, **kwargs: Any, @@ -2903,8 +2903,9 @@ def reduce( Function which can be called in the form `f(x, axis=axis, **kwargs)` to return the result of reducing an np.ndarray over an integer valued axis. - dim : Hashable or Iterable of Hashable, optional - Dimension(s) over which to apply `func`. + dim : "...", str, Iterable of Hashable or None, optional + Dimension(s) over which to apply `func`. By default `func` is + applied over all dimensions. axis : int or sequence of int, optional Axis(es) over which to repeatedly apply `func`. Only one of the 'dim' and 'axis' arguments can be supplied. If neither are @@ -3770,7 +3771,7 @@ def imag(self: T_DataArray) -> T_DataArray: def dot( self: T_DataArray, other: T_DataArray, - dims: str | Iterable[Hashable] | Ellipsis | None = None, + dims: Dims | ellipsis = None, ) -> T_DataArray: """Perform dot product of two DataArrays along their shared dims. @@ -3780,7 +3781,7 @@ def dot( ---------- other : DataArray The other array with which the dot product is performed. - dims : ..., str or Iterable of Hashable, optional + dims : ..., str, Iterable of Hashable or None, optional Which dimensions to sum over. Ellipsis (`...`) sums over all dimensions. If not specified, then all the common dimensions are summed over. @@ -3890,7 +3891,7 @@ def sortby( def quantile( self: T_DataArray, q: ArrayLike, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, method: QUANTILE_METHODS = "linear", keep_attrs: bool | None = None, skipna: bool | None = None, @@ -4774,7 +4775,7 @@ def idxmax( # https://github.com/python/mypy/issues/12846 is resolved def argmin( self, - dim: Hashable | Sequence[Hashable] | Ellipsis | None = None, + dim: Dims | ellipsis = None, axis: int | None = None, keep_attrs: bool | None = None, skipna: bool | None = None, @@ -4790,7 +4791,7 @@ def argmin( Parameters ---------- - dim : Hashable, sequence of Hashable, None or ..., optional + dim : "...", str, Iterable of Hashable or None, optional The dimensions over which to find the minimum. By default, finds minimum over all dimensions - for now returning an int for backward compatibility, but this is deprecated, in future will return a dict with indices for all @@ -4879,7 +4880,7 @@ def argmin( # https://github.com/python/mypy/issues/12846 is resolved def argmax( self, - dim: Hashable | Sequence[Hashable] | Ellipsis | None = None, + dim: Dims | ellipsis = None, axis: int | None = None, keep_attrs: bool | None = None, skipna: bool | None = None, @@ -4895,7 +4896,7 @@ def argmax( Parameters ---------- - dim : Hashable, sequence of Hashable, None or ..., optional + dim : "...", str, Iterable of Hashable or None, optional The dimensions over which to find the maximum. By default, finds maximum over all dimensions - for now returning an int for backward compatibility, but this is deprecated, in future will return a dict with indices for all @@ -5063,7 +5064,7 @@ def curvefit( self, coords: str | DataArray | Iterable[str | DataArray], func: Callable[..., Any], - reduce_dims: Hashable | Iterable[Hashable] | None = None, + reduce_dims: Dims = None, skipna: bool = True, p0: dict[str, Any] | None = None, bounds: dict[str, Any] | None = None, @@ -5088,7 +5089,7 @@ def curvefit( array of length `len(x)`. `params` are the fittable parameters which are optimized by scipy curve_fit. `x` can also be specified as a sequence containing multiple coordinates, e.g. `f((x0, x1), *params)`. - reduce_dims : Hashable or sequence of Hashable + reduce_dims : str, Iterable of Hashable or None, optional Additional dimension(s) over which to aggregate while fitting. For example, calling `ds.curvefit(coords='time', reduce_dims=['lat', 'lon'], ...)` will aggregate all lat and lon points and fit the specified function along the diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 08a2d04cab8..a7c4e1997b6 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -107,7 +107,7 @@ CombineAttrsOptions, CompatOptions, DatetimeUnitOptions, - Ellipsis, + Dims, ErrorOptions, ErrorOptionsWithWarn, InterpOptions, @@ -1698,14 +1698,14 @@ def set_coords(self: T_Dataset, names: Hashable | Iterable[Hashable]) -> T_Datas def reset_coords( self: T_Dataset, - names: Hashable | Iterable[Hashable] | None = None, + names: Dims = None, drop: bool = False, ) -> T_Dataset: """Given names of coordinates, reset them to become variables Parameters ---------- - names : hashable or iterable of hashable, optional + names : str, Iterable of Hashable or None, optional Name(s) of non-index coordinates in this dataset to reset into variables. By default, all non-index coordinates are reset. drop : bool, default: False @@ -4256,7 +4256,7 @@ def _get_stack_index( def _stack_once( self: T_Dataset, - dims: Sequence[Hashable | Ellipsis], + dims: Sequence[Hashable | ellipsis], new_dim: Hashable, index_cls: type[Index], create_index: bool | None = True, @@ -4315,10 +4315,10 @@ def _stack_once( def stack( self: T_Dataset, - dimensions: Mapping[Any, Sequence[Hashable | Ellipsis]] | None = None, + dimensions: Mapping[Any, Sequence[Hashable | ellipsis]] | None = None, create_index: bool | None = True, index_cls: type[Index] = PandasMultiIndex, - **dimensions_kwargs: Sequence[Hashable | Ellipsis], + **dimensions_kwargs: Sequence[Hashable | ellipsis], ) -> T_Dataset: """ Stack any number of existing dimensions into a single new dimension. @@ -4569,7 +4569,7 @@ def _unstack_full_reindex( def unstack( self: T_Dataset, - dim: Hashable | Iterable[Hashable] | None = None, + dim: Dims = None, fill_value: Any = xrdtypes.NA, sparse: bool = False, ) -> T_Dataset: @@ -4581,7 +4581,7 @@ def unstack( Parameters ---------- - dim : hashable or iterable of hashable, optional + dim : str, Iterable of Hashable or None, optional Dimension(s) over which to unstack. By default unstacks all MultiIndexes. fill_value : scalar or dict-like, default: nan @@ -4659,15 +4659,13 @@ def unstack( for v in nonindexes ) - for dim in dims: + for d in dims: if needs_full_reindex: result = result._unstack_full_reindex( - dim, stacked_indexes[dim], fill_value, sparse + d, stacked_indexes[d], fill_value, sparse ) else: - result = result._unstack_once( - dim, stacked_indexes[dim], fill_value, sparse - ) + result = result._unstack_once(d, stacked_indexes[d], fill_value, sparse) return result def update(self: T_Dataset, other: CoercibleMapping) -> T_Dataset: @@ -5065,7 +5063,7 @@ def drop_isel(self: T_Dataset, indexers=None, **indexers_kwargs) -> T_Dataset: def drop_dims( self: T_Dataset, - drop_dims: Hashable | Iterable[Hashable], + drop_dims: str | Iterable[Hashable], *, errors: ErrorOptions = "raise", ) -> T_Dataset: @@ -5073,7 +5071,7 @@ def drop_dims( Parameters ---------- - drop_dims : hashable or iterable of hashable + drop_dims : str or Iterable of Hashable Dimension or dimensions to drop. errors : {"raise", "ignore"}, default: "raise" If 'raise', raises a ValueError error if any of the @@ -5504,7 +5502,7 @@ def combine_first(self: T_Dataset, other: T_Dataset) -> T_Dataset: def reduce( self: T_Dataset, func: Callable, - dim: Hashable | Iterable[Hashable] = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, keepdims: bool = False, @@ -5519,8 +5517,8 @@ def reduce( Function which can be called in the form `f(x, axis=axis, **kwargs)` to return the result of reducing an np.ndarray over an integer valued axis. - dim : str or sequence of str, optional - Dimension(s) over which to apply `func`. By default `func` is + dim : str, Iterable of Hashable or None, optional + Dimension(s) over which to apply `func`. By default `func` is applied over all dimensions. keep_attrs : bool or None, optional If True, the dataset's attributes (`attrs`) will be copied from @@ -5578,18 +5576,15 @@ def reduce( or np.issubdtype(var.dtype, np.number) or (var.dtype == np.bool_) ): - reduce_maybe_single: Hashable | None | list[Hashable] - if len(reduce_dims) == 1: - # unpack dimensions for the benefit of functions - # like np.argmin which can't handle tuple arguments - (reduce_maybe_single,) = reduce_dims - elif len(reduce_dims) == var.ndim: - # prefer to aggregate over axis=None rather than - # axis=(0, 1) if they will be equivalent, because - # the former is often more efficient - reduce_maybe_single = None - else: - reduce_maybe_single = reduce_dims + # prefer to aggregate over axis=None rather than + # axis=(0, 1) if they will be equivalent, because + # the former is often more efficient + # keep single-element dims as list, to support Hashables + reduce_maybe_single = ( + None + if len(reduce_dims) == var.ndim and var.ndim != 1 + else reduce_dims + ) variables[name] = var.reduce( func, dim=reduce_maybe_single, @@ -6698,7 +6693,7 @@ def sortby( def quantile( self: T_Dataset, q: ArrayLike, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, method: QUANTILE_METHODS = "linear", numeric_only: bool = False, keep_attrs: bool = None, @@ -8030,7 +8025,9 @@ def argmin(self: T_Dataset, dim: Hashable | None = None, **kwargs) -> T_Dataset: # Return int index if single dimension is passed, and is not part of a # sequence argmin_func = getattr(duck_array_ops, "argmin") - return self.reduce(argmin_func, dim=dim, **kwargs) + return self.reduce( + argmin_func, dim=None if dim is None else [dim], **kwargs + ) else: raise ValueError( "When dim is a sequence or ..., DataArray.argmin() returns a dict. " @@ -8088,7 +8085,9 @@ def argmax(self: T_Dataset, dim: Hashable | None = None, **kwargs) -> T_Dataset: # Return int index if single dimension is passed, and is not part of a # sequence argmax_func = getattr(duck_array_ops, "argmax") - return self.reduce(argmax_func, dim=dim, **kwargs) + return self.reduce( + argmax_func, dim=None if dim is None else [dim], **kwargs + ) else: raise ValueError( "When dim is a sequence or ..., DataArray.argmin() returns a dict. " @@ -8196,7 +8195,7 @@ def curvefit( self: T_Dataset, coords: str | DataArray | Iterable[str | DataArray], func: Callable[..., Any], - reduce_dims: Hashable | Iterable[Hashable] | None = None, + reduce_dims: Dims = None, skipna: bool = True, p0: dict[str, Any] | None = None, bounds: dict[str, Any] | None = None, @@ -8221,7 +8220,7 @@ def curvefit( array of length `len(x)`. `params` are the fittable parameters which are optimized by scipy curve_fit. `x` can also be specified as a sequence containing multiple coordinates, e.g. `f((x0, x1), *params)`. - reduce_dims : hashable or sequence of hashable + reduce_dims : str, Iterable of Hashable or None, optional Additional dimension(s) over which to aggregate while fitting. For example, calling `ds.curvefit(coords='time', reduce_dims=['lat', 'lon'], ...)` will aggregate all lat and lon points and fit the specified function along the @@ -8272,6 +8271,7 @@ def curvefit( if kwargs is None: kwargs = {} + reduce_dims_: list[Hashable] if not reduce_dims: reduce_dims_ = [] elif isinstance(reduce_dims, str) or not isinstance(reduce_dims, Iterable): diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py index e7b1a450cc9..8a21406be2b 100644 --- a/xarray/core/groupby.py +++ b/xarray/core/groupby.py @@ -8,7 +8,6 @@ Callable, Generic, Hashable, - Iterable, Iterator, Literal, Mapping, @@ -33,7 +32,7 @@ from .ops import IncludeCumMethods from .options import _get_keep_attrs from .pycompat import integer_types -from .types import T_Xarray +from .types import Dims, T_Xarray from .utils import ( either_dict_or_kwargs, hashable, @@ -463,7 +462,7 @@ def __init__( # cached attributes self._groups: dict[GroupKey, slice | int | list[int]] | None = None - self._dims = None + self._dims: tuple[Hashable, ...] | Frozen[Hashable, int] | None = None self._sizes: Frozen[Hashable, int] | None = None @property @@ -496,9 +495,9 @@ def map( def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Iterable[Hashable] = None, + dim: Dims | ellipsis = None, *, - axis: None | int | Sequence[int] = None, + axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, shortcut: bool = True, @@ -653,7 +652,12 @@ def _maybe_unstack(self, obj): obj._indexes = filter_indexes_from_coords(obj._indexes, set(obj.coords)) return obj - def _flox_reduce(self, dim, keep_attrs=None, **kwargs): + def _flox_reduce( + self, + dim: Dims | ellipsis, + keep_attrs: bool | None = None, + **kwargs: Any, + ): """Adaptor function that translates our groupby API to that of flox.""" from flox.xarray import xarray_reduce @@ -697,24 +701,31 @@ def _flox_reduce(self, dim, keep_attrs=None, **kwargs): else: group = self._original_group - unindexed_dims = tuple() + unindexed_dims: tuple[str, ...] = tuple() if isinstance(group, str): if group in obj.dims and group not in obj._indexes and self._bins is None: unindexed_dims = (group,) group = self._original_obj[group] + parsed_dim: tuple[Hashable, ...] if isinstance(dim, str): - dim = (dim,) + parsed_dim = (dim,) elif dim is None: - dim = group.dims - elif dim is Ellipsis: - dim = tuple(self._original_obj.dims) + parsed_dim = group.dims + elif dim is ...: + parsed_dim = tuple(self._original_obj.dims) + else: + parsed_dim = tuple(dim) # type:ignore[arg-type] # Do this so we raise the same error message whether flox is present or not. # Better to control it here than in flox. - if any(d not in group.dims and d not in self._original_obj.dims for d in dim): + if any( + d not in group.dims and d not in self._original_obj.dims for d in parsed_dim + ): raise ValueError(f"cannot reduce over dimensions {dim}.") + expected_groups: tuple[np.ndarray | Any, ...] + isbin: bool | Sequence[bool] if self._bins is not None: # TODO: fix this; When binning by time, self._bins is a DatetimeIndex expected_groups = (np.array(self._bins),) @@ -738,7 +749,7 @@ def _flox_reduce(self, dim, keep_attrs=None, **kwargs): result = xarray_reduce( self._original_obj.drop_vars(non_numeric), group, - dim=dim, + dim=parsed_dim, # type:ignore[arg-type] # https://github.com/xarray-contrib/flox/issues/96 expected_groups=expected_groups, isbin=isbin, keep_attrs=keep_attrs, @@ -751,7 +762,7 @@ def _flox_reduce(self, dim, keep_attrs=None, **kwargs): # broadcast and restore non-numeric data variables (backcompat) for name, var in non_numeric.items(): - if all(d not in var.dims for d in dim): + if all(d not in var.dims for d in parsed_dim): result[name] = var.variable.set_dims( (group.name,) + var.dims, (result.sizes[group.name],) + var.shape ) @@ -760,6 +771,7 @@ def _flox_reduce(self, dim, keep_attrs=None, **kwargs): # bins provided to flox are at full precision # the bin edge labels have a default precision of 3 # reassign to fix that. + assert self._full_index is not None new_coord = [ pd.Interval(inter.left, inter.right) for inter in self._full_index ] @@ -801,7 +813,7 @@ def fillna(self, value: Any) -> T_Xarray: def quantile( self, q: ArrayLike, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, method: QUANTILE_METHODS = "linear", keep_attrs: bool | None = None, skipna: bool | None = None, @@ -966,7 +978,9 @@ def _first_or_last(self, op, skipna, keep_attrs): return self._obj if keep_attrs is None: keep_attrs = _get_keep_attrs(default=True) - return self.reduce(op, self._group_dim, skipna=skipna, keep_attrs=keep_attrs) + return self.reduce( + op, dim=[self._group_dim], skipna=skipna, keep_attrs=keep_attrs + ) def first(self, skipna: bool | None = None, keep_attrs: bool | None = None): """Return the first element of each group along the group dimension""" @@ -1134,10 +1148,10 @@ def _combine(self, applied, shortcut=False): def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Iterable[Hashable] = None, + dim: Dims | ellipsis = None, *, - axis: None | int | Sequence[int] = None, - keep_attrs: bool = None, + axis: int | Sequence[int] | None = None, + keep_attrs: bool | None = None, keepdims: bool = False, shortcut: bool = True, **kwargs: Any, @@ -1151,8 +1165,9 @@ def reduce( Function which can be called in the form `func(x, axis=axis, **kwargs)` to return the result of collapsing an np.ndarray over an integer valued axis. - dim : ..., str or sequence of str, optional - Dimension(s) over which to apply `func`. + dim : "...", str, Iterable of Hashable or None, optional + Dimension(s) over which to apply `func`. If None, apply over the + groupby dimension, if "..." apply over all dimensions. axis : int or sequence of int, optional Axis(es) over which to apply `func`. Only one of the 'dimension' and 'axis' arguments can be supplied. If neither are supplied, then @@ -1171,7 +1186,7 @@ def reduce( removed. """ if dim is None: - dim = self._group_dim + dim = [self._group_dim] if keep_attrs is None: keep_attrs = _get_keep_attrs(default=True) @@ -1287,10 +1302,10 @@ def _combine(self, applied): def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Iterable[Hashable] = None, + dim: Dims | ellipsis = None, *, - axis: None | int | Sequence[int] = None, - keep_attrs: bool = None, + axis: int | Sequence[int] | None = None, + keep_attrs: bool | None = None, keepdims: bool = False, shortcut: bool = True, **kwargs: Any, @@ -1304,8 +1319,9 @@ def reduce( Function which can be called in the form `func(x, axis=axis, **kwargs)` to return the result of collapsing an np.ndarray over an integer valued axis. - dim : ..., str or Iterable of Hashable, optional - Dimension(s) over which to apply `func`. + dim : ..., str, Iterable of Hashable or None, optional + Dimension(s) over which to apply `func`. By default apply over the + groupby dimension, with "..." apply over all dimensions. axis : int or sequence of int, optional Axis(es) over which to apply `func`. Only one of the 'dimension' and 'axis' arguments can be supplied. If neither are supplied, then @@ -1324,7 +1340,7 @@ def reduce( removed. """ if dim is None: - dim = self._group_dim + dim = [self._group_dim] if keep_attrs is None: keep_attrs = _get_keep_attrs(default=True) diff --git a/xarray/core/resample.py b/xarray/core/resample.py index bf9c9f7501a..d4fb46dea0c 100644 --- a/xarray/core/resample.py +++ b/xarray/core/resample.py @@ -7,7 +7,7 @@ from ._reductions import DataArrayResampleReductions, DatasetResampleReductions from .groupby import DataArrayGroupByBase, DatasetGroupByBase, GroupBy -from .types import InterpOptions, T_Xarray +from .types import Dims, InterpOptions, T_Xarray if TYPE_CHECKING: from .dataarray import DataArray @@ -48,7 +48,12 @@ def __init__( super().__init__(*args, **kwargs) - def _flox_reduce(self, dim, keep_attrs: bool | None = None, **kwargs) -> T_Xarray: + def _flox_reduce( + self, + dim: Dims | ellipsis, + keep_attrs: bool | None = None, + **kwargs, + ) -> T_Xarray: from .dataarray import DataArray @@ -287,7 +292,7 @@ def asfreq(self) -> DataArray: resampled : DataArray """ self._obj = self._drop_coords() - return self.mean(self._dim) + return self.mean(None if self._dim is None else [self._dim]) # https://github.com/python/mypy/issues/9031 @@ -355,10 +360,10 @@ def apply(self, func, args=(), shortcut=None, **kwargs): def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Iterable[Hashable] = None, + dim: Dims | ellipsis = None, *, - axis: None | int | Sequence[int] = None, - keep_attrs: bool = None, + axis: int | Sequence[int] | None = None, + keep_attrs: bool | None = None, keepdims: bool = False, shortcut: bool = True, **kwargs: Any, @@ -372,7 +377,7 @@ def reduce( Function which can be called in the form `func(x, axis=axis, **kwargs)` to return the result of collapsing an np.ndarray over an integer valued axis. - dim : Hashable or Iterable of Hashable, optional + dim : "...", str, Iterable of Hashable or None, optional Dimension(s) over which to apply `func`. keep_attrs : bool, optional If True, the datasets's attributes (`attrs`) will be copied from @@ -406,4 +411,4 @@ def asfreq(self) -> Dataset: resampled : Dataset """ self._obj = self._drop_coords() - return self.mean(self._dim) + return self.mean(None if self._dim is None else [self._dim]) diff --git a/xarray/core/rolling.py b/xarray/core/rolling.py index fc297f33cd9..37da08d6ed6 100644 --- a/xarray/core/rolling.py +++ b/xarray/core/rolling.py @@ -281,7 +281,7 @@ def __iter__(self) -> Iterator[tuple[DataArray, DataArray]]: for (label, start, stop) in zip(self.window_labels, starts, stops): window = self.obj.isel({dim0: slice(start, stop)}) - counts = window.count(dim=dim0) + counts = window.count(dim=[dim0]) window = window.where(counts >= self.min_periods) yield (label, window) diff --git a/xarray/core/types.py b/xarray/core/types.py index a1477757b6e..5b45f6d803b 100644 --- a/xarray/core/types.py +++ b/xarray/core/types.py @@ -1,6 +1,16 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Literal, Sequence, TypeVar, Union +from typing import ( + TYPE_CHECKING, + Any, + Callable, + Hashable, + Iterable, + Literal, + Sequence, + TypeVar, + Union, +) import numpy as np @@ -32,11 +42,8 @@ # Self: Any = None Self: Any = None - Ellipsis = ellipsis - else: Self: Any = None - Ellipsis: Any = None T_Dataset = TypeVar("T_Dataset", bound="Dataset") @@ -57,6 +64,8 @@ VarCompatible = Union["Variable", "ScalarOrArray"] GroupByIncompatible = Union["Variable", "GroupBy"] +Dims = Union[str, Iterable[Hashable], None] + ErrorOptions = Literal["raise", "ignore"] ErrorOptionsWithWarn = Literal["raise", "warn", "ignore"] diff --git a/xarray/core/variable.py b/xarray/core/variable.py index cfe1db6a24e..058bbb129cd 100644 --- a/xarray/core/variable.py +++ b/xarray/core/variable.py @@ -66,7 +66,7 @@ if TYPE_CHECKING: from .types import ( - Ellipsis, + Dims, ErrorOptionsWithWarn, PadModeOptions, PadReflectOptions, @@ -1474,7 +1474,7 @@ def roll(self, shifts=None, **shifts_kwargs): def transpose( self, - *dims: Hashable | Ellipsis, + *dims: Hashable | ellipsis, missing_dims: ErrorOptionsWithWarn = "raise", ) -> Variable: """Return a new Variable object with transposed dimensions. @@ -1796,7 +1796,7 @@ def clip(self, min=None, max=None): def reduce( self, func: Callable[..., Any], - dim: Hashable | Iterable[Hashable] | None = None, + dim: Dims | ellipsis = None, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, @@ -1810,8 +1810,9 @@ def reduce( Function which can be called in the form `func(x, axis=axis, **kwargs)` to return the result of reducing an np.ndarray over an integer valued axis. - dim : Hashable or Iterable of Hashable, optional - Dimension(s) over which to apply `func`. + dim : "...", str, Iterable of Hashable or None, optional + Dimension(s) over which to apply `func`. By default `func` is + applied over all dimensions. axis : int or Sequence of int, optional Axis(es) over which to apply `func`. Only one of the 'dim' and 'axis' arguments can be supplied. If neither are supplied, then @@ -1846,6 +1847,10 @@ def reduce( "ignore", r"Mean of empty slice", category=RuntimeWarning ) if axis is not None: + if isinstance(axis, tuple) and len(axis) == 1: + # unpack axis for the benefit of functions + # like np.argmin which can't handle tuple arguments + axis = axis[0] data = func(self.data, axis=axis, **kwargs) else: data = func(self.data, **kwargs) @@ -2551,7 +2556,7 @@ def _to_numeric(self, offset=None, datetime_unit=None, dtype=float): def _unravel_argminmax( self, argminmax: str, - dim: Hashable | Sequence[Hashable] | Ellipsis | None, + dim: Dims | ellipsis, axis: int | None, keep_attrs: bool | None, skipna: bool | None, @@ -2620,7 +2625,7 @@ def _unravel_argminmax( def argmin( self, - dim: Hashable | Sequence[Hashable] | Ellipsis | None = None, + dim: Dims | ellipsis = None, axis: int = None, keep_attrs: bool = None, skipna: bool = None, @@ -2635,7 +2640,7 @@ def argmin( Parameters ---------- - dim : hashable, sequence of hashable or ..., optional + dim : "...", str, Iterable of Hashable or None, optional The dimensions over which to find the minimum. By default, finds minimum over all dimensions - for now returning an int for backward compatibility, but this is deprecated, in future will return a dict with indices for all @@ -2665,7 +2670,7 @@ def argmin( def argmax( self, - dim: Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, axis: int = None, keep_attrs: bool = None, skipna: bool = None, @@ -2680,7 +2685,7 @@ def argmax( Parameters ---------- - dim : hashable, sequence of hashable or ..., optional + dim : "...", str, Iterable of Hashable or None, optional The dimensions over which to find the maximum. By default, finds maximum over all dimensions - for now returning an int for backward compatibility, but this is deprecated, in future will return a dict with indices for all diff --git a/xarray/core/weighted.py b/xarray/core/weighted.py index 9d5be6f7126..a89b29723b4 100644 --- a/xarray/core/weighted.py +++ b/xarray/core/weighted.py @@ -9,7 +9,7 @@ from .computation import apply_ufunc, dot from .npcompat import ArrayLike from .pycompat import is_duck_dask_array -from .types import Ellipsis, T_Xarray +from .types import Dims, T_Xarray # Weighted quantile methods are a subset of the numpy supported quantile methods. QUANTILE_METHODS = Literal[ @@ -189,9 +189,10 @@ def _weight_check(w): self.obj: T_Xarray = obj self.weights: DataArray = weights - def _check_dim(self, dim: Hashable | Iterable[Hashable] | None): + def _check_dim(self, dim: Dims): """raise an error if any dimension is missing""" + dims: list[Hashable] if isinstance(dim, str) or not isinstance(dim, Iterable): dims = [dim] if dim else [] else: @@ -206,7 +207,7 @@ def _check_dim(self, dim: Hashable | Iterable[Hashable] | None): def _reduce( da: DataArray, weights: DataArray, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: Dims | ellipsis = None, skipna: bool | None = None, ) -> DataArray: """reduce using dot; equivalent to (da * weights).sum(dim, skipna) @@ -226,9 +227,7 @@ def _reduce( # DataArray (if `weights` has additional dimensions) return dot(da, weights, dims=dim) - def _sum_of_weights( - self, da: DataArray, dim: str | Iterable[Hashable] | None = None - ) -> DataArray: + def _sum_of_weights(self, da: DataArray, dim: Dims = None) -> DataArray: """Calculate the sum of weights, accounting for missing values""" # we need to mask data values that are nan; else the weights are wrong @@ -251,7 +250,7 @@ def _sum_of_weights( def _sum_of_squares( self, da: DataArray, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, skipna: bool | None = None, ) -> DataArray: """Reduce a DataArray by a weighted ``sum_of_squares`` along some dimension(s).""" @@ -263,7 +262,7 @@ def _sum_of_squares( def _weighted_sum( self, da: DataArray, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, skipna: bool | None = None, ) -> DataArray: """Reduce a DataArray by a weighted ``sum`` along some dimension(s).""" @@ -273,7 +272,7 @@ def _weighted_sum( def _weighted_mean( self, da: DataArray, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, skipna: bool | None = None, ) -> DataArray: """Reduce a DataArray by a weighted ``mean`` along some dimension(s).""" @@ -287,7 +286,7 @@ def _weighted_mean( def _weighted_var( self, da: DataArray, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, skipna: bool | None = None, ) -> DataArray: """Reduce a DataArray by a weighted ``var`` along some dimension(s).""" @@ -301,7 +300,7 @@ def _weighted_var( def _weighted_std( self, da: DataArray, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, skipna: bool | None = None, ) -> DataArray: """Reduce a DataArray by a weighted ``std`` along some dimension(s).""" @@ -312,7 +311,7 @@ def _weighted_quantile( self, da: DataArray, q: ArrayLike, - dim: Hashable | Iterable[Hashable] | None = None, + dim: Dims = None, skipna: bool = None, ) -> DataArray: """Apply a weighted ``quantile`` to a DataArray along some dimension(s).""" @@ -449,7 +448,7 @@ def _implementation(self, func, dim, **kwargs): def sum_of_weights( self, - dim: Hashable | Iterable[Hashable] | None = None, + dim: Dims = None, keep_attrs: bool | None = None, ) -> T_Xarray: @@ -459,7 +458,7 @@ def sum_of_weights( def sum_of_squares( self, - dim: Hashable | Iterable[Hashable] | None = None, + dim: Dims = None, skipna: bool | None = None, keep_attrs: bool | None = None, ) -> T_Xarray: @@ -470,7 +469,7 @@ def sum_of_squares( def sum( self, - dim: Hashable | Iterable[Hashable] | None = None, + dim: Dims = None, skipna: bool | None = None, keep_attrs: bool | None = None, ) -> T_Xarray: @@ -481,7 +480,7 @@ def sum( def mean( self, - dim: Hashable | Iterable[Hashable] | None = None, + dim: Dims = None, skipna: bool | None = None, keep_attrs: bool | None = None, ) -> T_Xarray: @@ -492,7 +491,7 @@ def mean( def var( self, - dim: Hashable | Iterable[Hashable] | None = None, + dim: Dims = None, skipna: bool | None = None, keep_attrs: bool | None = None, ) -> T_Xarray: @@ -503,7 +502,7 @@ def var( def std( self, - dim: Hashable | Iterable[Hashable] | None = None, + dim: Dims = None, skipna: bool | None = None, keep_attrs: bool | None = None, ) -> T_Xarray: @@ -516,7 +515,7 @@ def quantile( self, q: ArrayLike, *, - dim: Hashable | Sequence[Hashable] | None = None, + dim: Dims = None, keep_attrs: bool = None, skipna: bool = True, ) -> T_Xarray: diff --git a/xarray/tests/test_dataarray.py b/xarray/tests/test_dataarray.py index ab6e5763248..5c1dc59aa23 100644 --- a/xarray/tests/test_dataarray.py +++ b/xarray/tests/test_dataarray.py @@ -6423,14 +6423,14 @@ def test_deepcopy_obj_array() -> None: def test_clip(da: DataArray) -> None: with raise_if_dask_computes(): result = da.clip(min=0.5) - assert result.min(...) >= 0.5 + assert result.min() >= 0.5 result = da.clip(max=0.5) - assert result.max(...) <= 0.5 + assert result.max() <= 0.5 result = da.clip(min=0.25, max=0.75) - assert result.min(...) >= 0.25 - assert result.max(...) <= 0.75 + assert result.min() >= 0.25 + assert result.max() <= 0.75 with raise_if_dask_computes(): result = da.clip(min=da.mean("x"), max=da.mean("a")) diff --git a/xarray/tests/test_dataset.py b/xarray/tests/test_dataset.py index e0bc73ec044..ffd95c9e87e 100644 --- a/xarray/tests/test_dataset.py +++ b/xarray/tests/test_dataset.py @@ -2674,12 +2674,13 @@ def test_drop_dims(self) -> None: data.drop_dims("z") # not a dimension with pytest.raises((ValueError, KeyError)): - data.drop_dims(None) + data.drop_dims(None) # type:ignore[arg-type] actual = data.drop_dims("z", errors="ignore") assert_identical(data, actual) - actual = data.drop_dims(None, errors="ignore") + # should this be allowed? + actual = data.drop_dims(None, errors="ignore") # type:ignore[arg-type] assert_identical(data, actual) with pytest.raises(ValueError): diff --git a/xarray/tests/test_plot.py b/xarray/tests/test_plot.py index f37c2fd7508..baeeb8a234e 100644 --- a/xarray/tests/test_plot.py +++ b/xarray/tests/test_plot.py @@ -2233,7 +2233,7 @@ def test_num_ticks(self): @pytest.mark.slow def test_map(self): assert self.g._finalized is False - self.g.map(plt.contourf, "x", "y", Ellipsis) + self.g.map(plt.contourf, "x", "y", ...) assert self.g._finalized is True self.g.map(lambda: None) diff --git a/xarray/util/generate_reductions.py b/xarray/util/generate_reductions.py index 279b7859032..92e9cc341c9 100644 --- a/xarray/util/generate_reductions.py +++ b/xarray/util/generate_reductions.py @@ -22,10 +22,11 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Hashable, Sequence +from typing import TYPE_CHECKING, Any, Callable, Sequence from . import duck_array_ops from .options import OPTIONS +from .types import Dims from .utils import contains_only_dask_or_numpy if TYPE_CHECKING: @@ -45,9 +46,9 @@ class {obj}{cls}Reductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, *, - axis: None | int | Sequence[int] = None, + axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, **kwargs: Any, @@ -62,9 +63,9 @@ class {obj}{cls}Reductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, - axis: None | int | Sequence[int] = None, + axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, **kwargs: Any, @@ -73,7 +74,7 @@ def reduce( def _flox_reduce( self, - dim: None | Hashable | Sequence[Hashable], + dim: Dims | ellipsis, **kwargs: Any, ) -> {obj}: raise NotImplementedError()""" @@ -86,9 +87,9 @@ class {obj}{cls}Reductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims | ellipsis = None, *, - axis: None | int | Sequence[int] = None, + axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, **kwargs: Any, @@ -97,7 +98,7 @@ def reduce( def _flox_reduce( self, - dim: None | Hashable | Sequence[Hashable], + dim: Dims | ellipsis, **kwargs: Any, ) -> {obj}: raise NotImplementedError()""" @@ -105,7 +106,21 @@ def _flox_reduce( TEMPLATE_REDUCTION_SIGNATURE = ''' def {method}( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: Dims = None, + *,{extra_kwargs} + keep_attrs: bool | None = None, + **kwargs: Any, + ) -> {obj}: + """ + Reduce this {obj}'s data by applying ``{method}`` along some dimension(s). + + Parameters + ----------''' + +TEMPLATE_REDUCTION_SIGNATURE_GROUPBY = ''' + def {method}( + self, + dim: Dims | ellipsis = None, *,{extra_kwargs} keep_attrs: bool | None = None, **kwargs: Any, @@ -137,10 +152,15 @@ def {method}( ----- {notes}""" -_DIM_DOCSTRING = """dim : hashable or iterable of hashable, default: None +_DIM_DOCSTRING = """dim : str, Iterable of Hashable, or None, default: None Name of dimension[s] along which to apply ``{method}``. For e.g. ``dim="x"`` or ``dim=["x", "y"]``. If None, will reduce over all dimensions.""" +_DIM_DOCSTRING_GROUPBY = """dim : str, Iterable of Hashable, "..." or None, default: None + Name of dimension[s] along which to apply ``{method}``. For e.g. ``dim="x"`` + or ``dim=["x", "y"]``. If None, will reduce over the {cls} dimensions. + If "...", will reduce over all dimensions.""" + _SKIPNA_DOCSTRING = """skipna : bool or None, optional If True, skip missing values (as marked by NaN). By default, only skips missing values for float dtypes; other dtypes either do not @@ -226,6 +246,10 @@ def __init__( class ReductionGenerator: + + _dim_docstring = _DIM_DOCSTRING + _template_signature = TEMPLATE_REDUCTION_SIGNATURE + def __init__( self, cls, @@ -264,13 +288,13 @@ def generate_method(self, method): else: extra_kwargs = "" - yield TEMPLATE_REDUCTION_SIGNATURE.format( + yield self._template_signature.format( **template_kwargs, extra_kwargs=extra_kwargs, ) for text in [ - _DIM_DOCSTRING.format(method=method.name), + self._dim_docstring.format(method=method.name, cls=self.cls), *(kwarg.docs for kwarg in method.extra_kwargs if kwarg.docs), _KEEP_ATTRS_DOCSTRING, _KWARGS_DOCSTRING.format(method=method.name), @@ -322,6 +346,9 @@ def generate_example(self, method): class GroupByReductionGenerator(ReductionGenerator): + _dim_docstring = _DIM_DOCSTRING_GROUPBY + _template_signature = TEMPLATE_REDUCTION_SIGNATURE_GROUPBY + def generate_code(self, method): extra_kwargs = [kwarg.call for kwarg in method.extra_kwargs if kwarg.call]