From d4cbad20ac25738408f3c38ec8d9744720e2793b Mon Sep 17 00:00:00 2001 From: Michael Niklas Date: Fri, 16 Sep 2022 22:56:34 +0200 Subject: [PATCH 01/11] update reductions typing to include ellipsis --- xarray/core/_reductions.py | 1425 +++++----------------------- xarray/util/generate_reductions.py | 53 +- 2 files changed, 278 insertions(+), 1200 deletions(-) diff --git a/xarray/core/_reductions.py b/xarray/core/_reductions.py index d2aebd3efa7..532ee8baede 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, Hashable, Iterable, Sequence from . import duck_array_ops from .options import OPTIONS +from .types import Ellipsis 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: str | Iterable[Hashable] | None = 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: str | Iterable[Hashable] | None = 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 @@ -84,19 +85,8 @@ def count( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.count() - - Dimensions: () - Data variables: - da int64 5 """ return self.reduce( duck_array_ops.count, @@ -108,7 +98,7 @@ def count( def all( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -118,7 +108,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 @@ -156,19 +146,8 @@ def all( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.all() - - Dimensions: () - Data variables: - da bool False """ return self.reduce( duck_array_ops.array_all, @@ -180,7 +159,7 @@ def all( def any( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -190,7 +169,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 @@ -228,19 +207,8 @@ def any( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.any() - - Dimensions: () - Data variables: - da bool True """ return self.reduce( duck_array_ops.array_any, @@ -252,7 +220,7 @@ def any( def max( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -263,7 +231,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 @@ -306,27 +274,12 @@ def max( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.max() - - Dimensions: () - Data variables: - da float64 3.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.max(skipna=False) - - Dimensions: () - Data variables: - da float64 nan """ return self.reduce( duck_array_ops.max, @@ -339,7 +292,7 @@ def max( def min( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -350,7 +303,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 @@ -393,27 +346,12 @@ def min( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.min() - - Dimensions: () - Data variables: - da float64 1.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.min(skipna=False) - - Dimensions: () - Data variables: - da float64 nan """ return self.reduce( duck_array_ops.min, @@ -426,7 +364,7 @@ def min( def mean( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -437,7 +375,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 @@ -484,27 +422,12 @@ def mean( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.mean() - - Dimensions: () - Data variables: - da float64 1.8 Use ``skipna`` to control whether NaNs are ignored. >>> ds.mean(skipna=False) - - Dimensions: () - Data variables: - da float64 nan """ return self.reduce( duck_array_ops.mean, @@ -517,7 +440,7 @@ def mean( def prod( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -529,7 +452,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 @@ -582,35 +505,16 @@ def prod( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.prod() - - Dimensions: () - Data variables: - da float64 12.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.prod(skipna=False) - - Dimensions: () - Data variables: - da float64 nan Specify ``min_count`` for finer control over when NaNs are ignored. >>> ds.prod(skipna=True, min_count=2) - - Dimensions: () - Data variables: - da float64 12.0 """ return self.reduce( duck_array_ops.prod, @@ -624,7 +528,7 @@ def prod( def sum( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -636,7 +540,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 @@ -689,35 +593,16 @@ def sum( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.sum() - - Dimensions: () - Data variables: - da float64 9.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.sum(skipna=False) - - Dimensions: () - Data variables: - da float64 nan Specify ``min_count`` for finer control over when NaNs are ignored. >>> ds.sum(skipna=True, min_count=2) - - Dimensions: () - Data variables: - da float64 9.0 """ return self.reduce( duck_array_ops.sum, @@ -731,7 +616,7 @@ def sum( def std( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -743,7 +628,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 @@ -793,35 +678,16 @@ def std( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.std() - - Dimensions: () - Data variables: - da float64 0.7483 Use ``skipna`` to control whether NaNs are ignored. >>> ds.std(skipna=False) - - Dimensions: () - Data variables: - da float64 nan Specify ``ddof=1`` for an unbiased estimate. >>> ds.std(skipna=True, ddof=1) - - Dimensions: () - Data variables: - da float64 0.8367 """ return self.reduce( duck_array_ops.std, @@ -835,7 +701,7 @@ def std( def var( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -847,7 +713,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 @@ -897,35 +763,16 @@ def var( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.var() - - Dimensions: () - Data variables: - da float64 0.56 Use ``skipna`` to control whether NaNs are ignored. >>> ds.var(skipna=False) - - Dimensions: () - Data variables: - da float64 nan Specify ``ddof=1`` for an unbiased estimate. >>> ds.var(skipna=True, ddof=1) - - Dimensions: () - Data variables: - da float64 0.7 """ return self.reduce( duck_array_ops.var, @@ -939,7 +786,7 @@ def var( def median( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -950,7 +797,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 @@ -997,27 +844,12 @@ def median( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.median() - - Dimensions: () - Data variables: - da float64 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.median(skipna=False) - - Dimensions: () - Data variables: - da float64 nan """ return self.reduce( duck_array_ops.median, @@ -1035,9 +867,9 @@ class DataArrayReductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = 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 +878,7 @@ def reduce( def count( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -1056,7 +888,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 @@ -1093,15 +925,8 @@ def count( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.count() - - array(5) """ return self.reduce( duck_array_ops.count, @@ -1112,7 +937,7 @@ def count( def all( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -1122,7 +947,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 @@ -1159,15 +984,8 @@ def all( ... ), ... ) >>> da - - array([ True, True, True, True, True, False]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.all() - - array(False) """ return self.reduce( duck_array_ops.array_all, @@ -1178,7 +996,7 @@ def all( def any( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -1188,7 +1006,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 @@ -1225,15 +1043,8 @@ def any( ... ), ... ) >>> da - - array([ True, True, True, True, True, False]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.any() - - array(True) """ return self.reduce( duck_array_ops.array_any, @@ -1244,7 +1055,7 @@ def any( def max( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1255,7 +1066,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 @@ -1297,21 +1108,12 @@ def max( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.max() - - array(3.) Use ``skipna`` to control whether NaNs are ignored. >>> da.max(skipna=False) - - array(nan) """ return self.reduce( duck_array_ops.max, @@ -1323,7 +1125,7 @@ def max( def min( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1334,7 +1136,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 @@ -1376,21 +1178,12 @@ def min( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.min() - - array(1.) Use ``skipna`` to control whether NaNs are ignored. >>> da.min(skipna=False) - - array(nan) """ return self.reduce( duck_array_ops.min, @@ -1402,7 +1195,7 @@ def min( def mean( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1413,7 +1206,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 @@ -1459,21 +1252,12 @@ def mean( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.mean() - - array(1.8) Use ``skipna`` to control whether NaNs are ignored. >>> da.mean(skipna=False) - - array(nan) """ return self.reduce( duck_array_ops.mean, @@ -1485,7 +1269,7 @@ def mean( def prod( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -1497,7 +1281,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 @@ -1549,27 +1333,16 @@ def prod( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.prod() - - array(12.) Use ``skipna`` to control whether NaNs are ignored. >>> da.prod(skipna=False) - - array(nan) Specify ``min_count`` for finer control over when NaNs are ignored. >>> da.prod(skipna=True, min_count=2) - - array(12.) """ return self.reduce( duck_array_ops.prod, @@ -1582,7 +1355,7 @@ def prod( def sum( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -1594,7 +1367,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 @@ -1646,27 +1419,16 @@ def sum( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.sum() - - array(9.) Use ``skipna`` to control whether NaNs are ignored. >>> da.sum(skipna=False) - - array(nan) Specify ``min_count`` for finer control over when NaNs are ignored. >>> da.sum(skipna=True, min_count=2) - - array(9.) """ return self.reduce( duck_array_ops.sum, @@ -1679,7 +1441,7 @@ def sum( def std( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -1691,7 +1453,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 @@ -1740,27 +1502,16 @@ def std( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.std() - - array(0.74833148) Use ``skipna`` to control whether NaNs are ignored. >>> da.std(skipna=False) - - array(nan) Specify ``ddof=1`` for an unbiased estimate. >>> da.std(skipna=True, ddof=1) - - array(0.83666003) """ return self.reduce( duck_array_ops.std, @@ -1773,7 +1524,7 @@ def std( def var( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -1785,7 +1536,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 @@ -1834,27 +1585,16 @@ def var( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.var() - - array(0.56) Use ``skipna`` to control whether NaNs are ignored. >>> da.var(skipna=False) - - array(nan) Specify ``ddof=1`` for an unbiased estimate. >>> da.var(skipna=True, ddof=1) - - array(0.7) """ return self.reduce( duck_array_ops.var, @@ -1867,7 +1607,7 @@ def var( def median( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1878,7 +1618,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 @@ -1924,21 +1664,12 @@ def median( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.median() - - array(2.) Use ``skipna`` to control whether NaNs are ignored. >>> da.median(skipna=False) - - array(nan) """ return self.reduce( duck_array_ops.median, @@ -1955,9 +1686,9 @@ class DatasetGroupByReductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = 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 +1697,14 @@ def reduce( def _flox_reduce( self, - dim: None | Hashable | Sequence[Hashable], + dim: str | Iterable[Hashable] | Ellipsis | None, **kwargs: Any, ) -> Dataset: raise NotImplementedError() def count( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -1983,9 +1714,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 @@ -2021,21 +1753,8 @@ def count( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.groupby("labels").count() - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) int64 1 2 2 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2057,7 +1776,7 @@ def count( def all( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -2067,9 +1786,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 @@ -2105,21 +1825,8 @@ def all( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.groupby("labels").all() - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) bool False True True """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2141,7 +1848,7 @@ def all( def any( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -2151,9 +1858,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 @@ -2189,21 +1897,8 @@ def any( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.groupby("labels").any() - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) bool True True True """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2225,7 +1920,7 @@ def any( def max( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -2236,9 +1931,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 @@ -2279,31 +1975,12 @@ def max( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.groupby("labels").max() - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 1.0 2.0 3.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").max(skipna=False) - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 nan 2.0 3.0 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2327,7 +2004,7 @@ def max( def min( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -2338,9 +2015,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 @@ -2381,31 +2059,12 @@ def min( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.groupby("labels").min() - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 1.0 2.0 1.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").min(skipna=False) - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 nan 2.0 1.0 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2429,7 +2088,7 @@ def min( def mean( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -2440,9 +2099,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 @@ -2487,31 +2147,12 @@ def mean( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.groupby("labels").mean() - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 1.0 2.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").mean(skipna=False) - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 nan 2.0 2.0 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2535,7 +2176,7 @@ def mean( def prod( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -2547,9 +2188,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 @@ -2600,41 +2242,16 @@ def prod( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.groupby("labels").prod() - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 1.0 4.0 3.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").prod(skipna=False) - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 nan 4.0 3.0 Specify ``min_count`` for finer control over when NaNs are ignored. >>> ds.groupby("labels").prod(skipna=True, min_count=2) - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 nan 4.0 3.0 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2660,7 +2277,7 @@ def prod( def sum( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -2672,9 +2289,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 @@ -2725,41 +2343,16 @@ def sum( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.groupby("labels").sum() - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 1.0 4.0 4.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").sum(skipna=False) - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 nan 4.0 4.0 Specify ``min_count`` for finer control over when NaNs are ignored. >>> ds.groupby("labels").sum(skipna=True, min_count=2) - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 nan 4.0 4.0 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2785,7 +2378,7 @@ def sum( def std( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -2797,9 +2390,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 @@ -2847,41 +2441,16 @@ def std( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.groupby("labels").std() - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 0.0 0.0 1.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").std(skipna=False) - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 nan 0.0 1.0 Specify ``ddof=1`` for an unbiased estimate. >>> ds.groupby("labels").std(skipna=True, ddof=1) - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 nan 0.0 1.414 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2907,7 +2476,7 @@ def std( def var( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -2919,9 +2488,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 @@ -2969,41 +2539,16 @@ def var( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.groupby("labels").var() - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 0.0 0.0 1.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").var(skipna=False) - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 nan 0.0 1.0 Specify ``ddof=1`` for an unbiased estimate. >>> ds.groupby("labels").var(skipna=True, ddof=1) - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 nan 0.0 2.0 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3029,7 +2574,7 @@ def var( def median( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3040,9 +2585,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 @@ -3087,31 +2633,12 @@ def median( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.groupby("labels").median() - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 1.0 2.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").median(skipna=False) - - Dimensions: (labels: 3) - Coordinates: - * labels (labels) object 'a' 'b' 'c' - Data variables: - da (labels) float64 nan 2.0 2.0 """ return self.reduce( duck_array_ops.median, @@ -3129,9 +2656,9 @@ class DatasetResampleReductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = 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 +2667,14 @@ def reduce( def _flox_reduce( self, - dim: None | Hashable | Sequence[Hashable], + dim: str | Iterable[Hashable] | Ellipsis | None, **kwargs: Any, ) -> Dataset: raise NotImplementedError() def count( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -3157,9 +2684,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 @@ -3195,21 +2723,8 @@ def count( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.resample(time="3M").count() - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) int64 1 3 1 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3231,7 +2746,7 @@ def count( def all( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -3241,9 +2756,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 @@ -3279,21 +2795,8 @@ def all( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.resample(time="3M").all() - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) bool True True False """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3315,7 +2818,7 @@ def all( def any( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -3325,9 +2828,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 @@ -3363,21 +2867,8 @@ def any( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.resample(time="3M").any() - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) bool True True True """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3399,7 +2890,7 @@ def any( def max( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3410,9 +2901,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 @@ -3453,31 +2945,12 @@ def max( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.resample(time="3M").max() - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 1.0 3.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").max(skipna=False) - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 1.0 3.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3501,7 +2974,7 @@ def max( def min( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3512,9 +2985,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 @@ -3555,31 +3029,12 @@ def min( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.resample(time="3M").min() - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 1.0 1.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").min(skipna=False) - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 1.0 1.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3603,7 +3058,7 @@ def min( def mean( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3614,9 +3069,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 @@ -3661,31 +3117,12 @@ def mean( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.resample(time="3M").mean() - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 1.0 2.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").mean(skipna=False) - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 1.0 2.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3709,7 +3146,7 @@ def mean( def prod( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -3721,9 +3158,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 @@ -3774,41 +3212,16 @@ def prod( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.resample(time="3M").prod() - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 1.0 6.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").prod(skipna=False) - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 1.0 6.0 nan Specify ``min_count`` for finer control over when NaNs are ignored. >>> ds.resample(time="3M").prod(skipna=True, min_count=2) - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 nan 6.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3834,7 +3247,7 @@ def prod( def sum( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -3846,9 +3259,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 @@ -3899,41 +3313,16 @@ def sum( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.resample(time="3M").sum() - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 1.0 6.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").sum(skipna=False) - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 1.0 6.0 nan Specify ``min_count`` for finer control over when NaNs are ignored. >>> ds.resample(time="3M").sum(skipna=True, min_count=2) - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 nan 6.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3959,7 +3348,7 @@ def sum( def std( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -3971,9 +3360,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 @@ -4021,41 +3411,16 @@ def std( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.resample(time="3M").std() - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 0.0 0.8165 0.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").std(skipna=False) - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 0.0 0.8165 nan Specify ``ddof=1`` for an unbiased estimate. >>> ds.resample(time="3M").std(skipna=True, ddof=1) - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 nan 1.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4081,7 +3446,7 @@ def std( def var( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -4093,9 +3458,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 @@ -4143,41 +3509,16 @@ def var( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.resample(time="3M").var() - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 0.0 0.6667 0.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").var(skipna=False) - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 0.0 0.6667 nan Specify ``ddof=1`` for an unbiased estimate. >>> ds.resample(time="3M").var(skipna=True, ddof=1) - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 nan 1.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4203,7 +3544,7 @@ def var( def median( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4214,9 +3555,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 @@ -4261,31 +3603,12 @@ def median( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds - - Dimensions: (time: 6) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> ds.resample(time="3M").median() - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 1.0 2.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").median(skipna=False) - - Dimensions: (time: 3) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 - Data variables: - da (time) float64 1.0 2.0 nan """ return self.reduce( duck_array_ops.median, @@ -4303,9 +3626,9 @@ class DataArrayGroupByReductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = 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 +3637,14 @@ def reduce( def _flox_reduce( self, - dim: None | Hashable | Sequence[Hashable], + dim: str | Iterable[Hashable] | Ellipsis | None, **kwargs: Any, ) -> DataArray: raise NotImplementedError() def count( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -4331,9 +3654,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 @@ -4368,17 +3692,8 @@ def count( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.groupby("labels").count() - - array([1, 2, 2]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4398,7 +3713,7 @@ def count( def all( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -4408,9 +3723,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 @@ -4445,17 +3761,8 @@ def all( ... ), ... ) >>> da - - array([ True, True, True, True, True, False]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.groupby("labels").all() - - array([False, True, True]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4475,7 +3782,7 @@ def all( def any( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -4485,9 +3792,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 @@ -4522,17 +3830,8 @@ def any( ... ), ... ) >>> da - - array([ True, True, True, True, True, False]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.groupby("labels").any() - - array([ True, True, True]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4552,7 +3851,7 @@ def any( def max( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4563,9 +3862,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 @@ -4605,25 +3905,12 @@ def max( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.groupby("labels").max() - - array([1., 2., 3.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").max(skipna=False) - - array([nan, 2., 3.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4645,7 +3932,7 @@ def max( def min( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4656,9 +3943,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 @@ -4698,25 +3986,12 @@ def min( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.groupby("labels").min() - - array([1., 2., 1.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").min(skipna=False) - - array([nan, 2., 1.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4738,7 +4013,7 @@ def min( def mean( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4749,9 +4024,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 @@ -4795,25 +4071,12 @@ def mean( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.groupby("labels").mean() - - array([1., 2., 2.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").mean(skipna=False) - - array([nan, 2., 2.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4835,7 +4098,7 @@ def mean( def prod( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -4847,9 +4110,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 @@ -4899,33 +4163,16 @@ def prod( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.groupby("labels").prod() - - array([1., 4., 3.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").prod(skipna=False) - - array([nan, 4., 3.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' Specify ``min_count`` for finer control over when NaNs are ignored. >>> da.groupby("labels").prod(skipna=True, min_count=2) - - array([nan, 4., 3.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4949,7 +4196,7 @@ def prod( def sum( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -4961,9 +4208,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 @@ -5013,33 +4261,16 @@ def sum( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.groupby("labels").sum() - - array([1., 4., 4.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").sum(skipna=False) - - array([nan, 4., 4.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' Specify ``min_count`` for finer control over when NaNs are ignored. >>> da.groupby("labels").sum(skipna=True, min_count=2) - - array([nan, 4., 4.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5063,7 +4294,7 @@ def sum( def std( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -5075,9 +4306,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 @@ -5124,33 +4356,16 @@ def std( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.groupby("labels").std() - - array([0., 0., 1.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").std(skipna=False) - - array([nan, 0., 1.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' Specify ``ddof=1`` for an unbiased estimate. >>> da.groupby("labels").std(skipna=True, ddof=1) - - array([ nan, 0. , 1.41421356]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5174,7 +4389,7 @@ def std( def var( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -5186,9 +4401,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 @@ -5235,33 +4451,16 @@ def var( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.groupby("labels").var() - - array([0., 0., 1.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").var(skipna=False) - - array([nan, 0., 1.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' Specify ``ddof=1`` for an unbiased estimate. >>> da.groupby("labels").var(skipna=True, ddof=1) - - array([nan, 0., 2.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5285,7 +4484,7 @@ def var( def median( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5296,9 +4495,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 @@ -5342,25 +4542,12 @@ def median( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.groupby("labels").median() - - array([1., 2., 2.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").median(skipna=False) - - array([nan, 2., 2.]) - Coordinates: - * labels (labels) object 'a' 'b' 'c' """ return self.reduce( duck_array_ops.median, @@ -5377,9 +4564,9 @@ class DataArrayResampleReductions: def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = 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 +4575,14 @@ def reduce( def _flox_reduce( self, - dim: None | Hashable | Sequence[Hashable], + dim: str | Iterable[Hashable] | Ellipsis | None, **kwargs: Any, ) -> DataArray: raise NotImplementedError() def count( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -5405,9 +4592,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 @@ -5442,17 +4630,8 @@ def count( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.resample(time="3M").count() - - array([1, 3, 1]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5472,7 +4651,7 @@ def count( def all( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -5482,9 +4661,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 @@ -5519,17 +4699,8 @@ def all( ... ), ... ) >>> da - - array([ True, True, True, True, True, False]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.resample(time="3M").all() - - array([ True, True, False]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5549,7 +4720,7 @@ def all( def any( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -5559,9 +4730,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 @@ -5596,17 +4768,8 @@ def any( ... ), ... ) >>> da - - array([ True, True, True, True, True, False]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.resample(time="3M").any() - - array([ True, True, True]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5626,7 +4789,7 @@ def any( def max( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5637,9 +4800,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 @@ -5679,25 +4843,12 @@ def max( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.resample(time="3M").max() - - array([1., 3., 2.]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").max(skipna=False) - - array([ 1., 3., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5719,7 +4870,7 @@ def max( def min( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5730,9 +4881,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 @@ -5772,25 +4924,12 @@ def min( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.resample(time="3M").min() - - array([1., 1., 2.]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").min(skipna=False) - - array([ 1., 1., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5812,7 +4951,7 @@ def min( def mean( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5823,9 +4962,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 @@ -5869,25 +5009,12 @@ def mean( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.resample(time="3M").mean() - - array([1., 2., 2.]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").mean(skipna=False) - - array([ 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5909,7 +5036,7 @@ def mean( def prod( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -5921,9 +5048,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 @@ -5973,33 +5101,16 @@ def prod( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.resample(time="3M").prod() - - array([1., 6., 2.]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").prod(skipna=False) - - array([ 1., 6., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Specify ``min_count`` for finer control over when NaNs are ignored. >>> da.resample(time="3M").prod(skipna=True, min_count=2) - - array([nan, 6., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -6023,7 +5134,7 @@ def prod( def sum( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -6035,9 +5146,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 @@ -6087,33 +5199,16 @@ def sum( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.resample(time="3M").sum() - - array([1., 6., 2.]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").sum(skipna=False) - - array([ 1., 6., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Specify ``min_count`` for finer control over when NaNs are ignored. >>> da.resample(time="3M").sum(skipna=True, min_count=2) - - array([nan, 6., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -6137,7 +5232,7 @@ def sum( def std( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -6149,9 +5244,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 @@ -6198,33 +5294,16 @@ def std( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.resample(time="3M").std() - - array([0. , 0.81649658, 0. ]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").std(skipna=False) - - array([0. , 0.81649658, nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Specify ``ddof=1`` for an unbiased estimate. >>> da.resample(time="3M").std(skipna=True, ddof=1) - - array([nan, 1., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -6248,7 +5327,7 @@ def std( def var( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -6260,9 +5339,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 @@ -6309,33 +5389,16 @@ def var( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.resample(time="3M").var() - - array([0. , 0.66666667, 0. ]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").var(skipna=False) - - array([0. , 0.66666667, nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Specify ``ddof=1`` for an unbiased estimate. >>> da.resample(time="3M").var(skipna=True, ddof=1) - - array([nan, 1., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -6359,7 +5422,7 @@ def var( def median( self, - dim: None | Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -6370,9 +5433,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 @@ -6416,25 +5480,12 @@ def median( ... ), ... ) >>> da - - array([ 1., 2., 3., 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 - labels (time) >> da.resample(time="3M").median() - - array([1., 2., 2.]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").median(skipna=False) - - array([ 1., 2., nan]) - Coordinates: - * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ return self.reduce( duck_array_ops.median, diff --git a/xarray/util/generate_reductions.py b/xarray/util/generate_reductions.py index 279b7859032..2ef64308677 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, Hashable, Iterable, Sequence from . import duck_array_ops from .options import OPTIONS +from .types import Ellipsis 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: str | Iterable[Hashable] | None = 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: str | Iterable[Hashable] | Ellipsis | None = 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: str | Iterable[Hashable] | Ellipsis | None, **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: str | Iterable[Hashable] | Ellipsis | None = 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: str | Iterable[Hashable] | Ellipsis | None, **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: str | Iterable[Hashable] | None = 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: str | Iterable[Hashable] | Ellipsis | None = 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] From 3ee697d0cd3d9fca586b96e3a96f005408a27f02 Mon Sep 17 00:00:00 2001 From: Michael Niklas Date: Fri, 16 Sep 2022 22:57:44 +0200 Subject: [PATCH 02/11] update all compatible interfaces to accept ellipsis --- xarray/core/dataarray.py | 7 ++-- xarray/core/dataset.py | 14 +++++--- xarray/core/groupby.py | 63 +++++++++++++++++++++------------- xarray/core/resample.py | 21 +++++++----- xarray/core/rolling.py | 2 +- xarray/core/variable.py | 5 +-- xarray/tests/test_dataarray.py | 8 ++--- 7 files changed, 73 insertions(+), 47 deletions(-) diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index 302562243b2..46e569c9972 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -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: Hashable | Iterable[Hashable] | Ellipsis | None = None, *, - axis: None | int | Sequence[int] = None, + axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, **kwargs: Any, @@ -2904,7 +2904,8 @@ def reduce( `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`. + 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 diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 08a2d04cab8..6058747026c 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -5504,7 +5504,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: str | Iterable[Hashable] | Ellipsis | None = None, *, keep_attrs: bool | None = None, keepdims: bool = False, @@ -5519,8 +5519,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 @@ -8030,7 +8030,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 +8090,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. " diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py index 9216248a945..0ee06d35a34 100644 --- a/xarray/core/groupby.py +++ b/xarray/core/groupby.py @@ -33,7 +33,7 @@ from .ops import IncludeCumMethods from .options import _get_keep_attrs from .pycompat import integer_types -from .types import T_Xarray +from .types import Ellipsis, T_Xarray from .utils import ( either_dict_or_kwargs, hashable, @@ -463,7 +463,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 +496,9 @@ def map( def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Iterable[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = 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 +653,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: str | Iterable[Hashable] | Ellipsis | None, + 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 +702,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 +750,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 +763,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 +772,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 ] @@ -1134,10 +1147,10 @@ def _combine(self, applied, shortcut=False): def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Iterable[Hashable] = None, + dim: Hashable | Iterable[Hashable] | Ellipsis | None = 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 +1164,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 : ..., Hashable, 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 @@ -1284,10 +1298,10 @@ def _combine(self, applied): def reduce( self, func: Callable[..., Any], - dim: None | Hashable | Iterable[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = 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, @@ -1301,8 +1315,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 @@ -1321,7 +1336,7 @@ def reduce( removed. """ if dim is None: - dim = self._group_dim + dim = [self._group_dim] def reduce_dataset(ds: Dataset) -> Dataset: return ds.reduce( diff --git a/xarray/core/resample.py b/xarray/core/resample.py index bf9c9f7501a..f1c7f4fbe83 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 Ellipsis, 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: str | Iterable[Hashable] | Ellipsis | None, + 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: str | Iterable[Hashable] | Ellipsis | None = 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/variable.py b/xarray/core/variable.py index c650464bbcb..c40a140e914 100644 --- a/xarray/core/variable.py +++ b/xarray/core/variable.py @@ -1801,7 +1801,7 @@ def clip(self, min=None, max=None): def reduce( self, func: Callable[..., Any], - dim: Hashable | Iterable[Hashable] | None = None, + dim: Hashable | Iterable[Hashable] | Ellipsis | None = None, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, @@ -1816,7 +1816,8 @@ def reduce( `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`. + 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 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")) From 4bc43354a0c3a0efdfb49e9bcda8260e9c3b9b0c Mon Sep 17 00:00:00 2001 From: Michael Niklas Date: Fri, 16 Sep 2022 23:10:41 +0200 Subject: [PATCH 03/11] change more dim types to str | Iterable[Hashable] --- xarray/core/dataarray.py | 12 ++++++------ xarray/core/dataset.py | 18 ++++++------------ xarray/core/groupby.py | 6 +++--- xarray/core/variable.py | 18 +++++++++++------- 4 files changed, 26 insertions(+), 28 deletions(-) diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index 46e569c9972..e4eb7592b1e 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -2888,7 +2888,7 @@ def combine_first(self: T_DataArray, other: T_DataArray) -> T_DataArray: def reduce( self: T_DataArray, func: Callable[..., Any], - dim: Hashable | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -2903,7 +2903,7 @@ 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 + 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 @@ -4775,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: str | Iterable[Hashable] | Ellipsis | None = None, axis: int | None = None, keep_attrs: bool | None = None, skipna: bool | None = None, @@ -4791,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 @@ -4880,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: str | Iterable[Hashable] | Ellipsis | None = None, axis: int | None = None, keep_attrs: bool | None = None, skipna: bool | None = None, @@ -4896,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 diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 6058747026c..55a3a7f3ed0 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -5578,18 +5578,12 @@ 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 + reduce_maybe_single = ( + None if len(reduce_dims) == var.ndim else reduce_dims + ) variables[name] = var.reduce( func, dim=reduce_maybe_single, diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py index 0ee06d35a34..69c45fbd32c 100644 --- a/xarray/core/groupby.py +++ b/xarray/core/groupby.py @@ -1147,7 +1147,7 @@ def _combine(self, applied, shortcut=False): def reduce( self, func: Callable[..., Any], - dim: Hashable | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -1164,7 +1164,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, Iterable of Hashable or None, optional + 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 @@ -1185,7 +1185,7 @@ def reduce( removed. """ if dim is None: - dim = self._group_dim + dim = [self._group_dim] def reduce_array(ar: DataArray) -> DataArray: return ar.reduce( diff --git a/xarray/core/variable.py b/xarray/core/variable.py index c40a140e914..537643ea187 100644 --- a/xarray/core/variable.py +++ b/xarray/core/variable.py @@ -1801,7 +1801,7 @@ def clip(self, min=None, max=None): def reduce( self, func: Callable[..., Any], - dim: Hashable | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, @@ -1815,7 +1815,7 @@ 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 + 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 @@ -1852,6 +1852,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) @@ -2557,7 +2561,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: str | Iterable[Hashable] | Ellipsis | None, axis: int | None, keep_attrs: bool | None, skipna: bool | None, @@ -2626,7 +2630,7 @@ def _unravel_argminmax( def argmin( self, - dim: Hashable | Sequence[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, axis: int = None, keep_attrs: bool = None, skipna: bool = None, @@ -2641,7 +2645,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 @@ -2671,7 +2675,7 @@ def argmin( def argmax( self, - dim: Hashable | Sequence[Hashable] = None, + dim: str | Iterable[Hashable] | Ellipsis | None = None, axis: int = None, keep_attrs: bool = None, skipna: bool = None, @@ -2686,7 +2690,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 From fb31762bbe12120a55a95f5b53df7838e9de337c Mon Sep 17 00:00:00 2001 From: Michael Niklas Date: Sat, 17 Sep 2022 13:19:13 +0200 Subject: [PATCH 04/11] re-add docstring examples --- xarray/core/_reductions.py | 994 +++++++++++++++++++++++++++++++++++++ 1 file changed, 994 insertions(+) diff --git a/xarray/core/_reductions.py b/xarray/core/_reductions.py index 532ee8baede..e16ebe4c19f 100644 --- a/xarray/core/_reductions.py +++ b/xarray/core/_reductions.py @@ -85,8 +85,19 @@ def count( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.count() + + Dimensions: () + Data variables: + da int32 5 """ return self.reduce( duck_array_ops.count, @@ -146,8 +157,19 @@ def all( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.all() + + Dimensions: () + Data variables: + da bool False """ return self.reduce( duck_array_ops.array_all, @@ -207,8 +229,19 @@ def any( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.any() + + Dimensions: () + Data variables: + da bool True """ return self.reduce( duck_array_ops.array_any, @@ -274,12 +307,27 @@ def max( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.max() + + Dimensions: () + Data variables: + da float64 3.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.max(skipna=False) + + Dimensions: () + Data variables: + da float64 nan """ return self.reduce( duck_array_ops.max, @@ -346,12 +394,27 @@ def min( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.min() + + Dimensions: () + Data variables: + da float64 1.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.min(skipna=False) + + Dimensions: () + Data variables: + da float64 nan """ return self.reduce( duck_array_ops.min, @@ -422,12 +485,27 @@ def mean( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.mean() + + Dimensions: () + Data variables: + da float64 1.8 Use ``skipna`` to control whether NaNs are ignored. >>> ds.mean(skipna=False) + + Dimensions: () + Data variables: + da float64 nan """ return self.reduce( duck_array_ops.mean, @@ -505,16 +583,35 @@ def prod( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.prod() + + Dimensions: () + Data variables: + da float64 12.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.prod(skipna=False) + + Dimensions: () + Data variables: + da float64 nan Specify ``min_count`` for finer control over when NaNs are ignored. >>> ds.prod(skipna=True, min_count=2) + + Dimensions: () + Data variables: + da float64 12.0 """ return self.reduce( duck_array_ops.prod, @@ -593,16 +690,35 @@ def sum( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.sum() + + Dimensions: () + Data variables: + da float64 9.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.sum(skipna=False) + + Dimensions: () + Data variables: + da float64 nan Specify ``min_count`` for finer control over when NaNs are ignored. >>> ds.sum(skipna=True, min_count=2) + + Dimensions: () + Data variables: + da float64 9.0 """ return self.reduce( duck_array_ops.sum, @@ -678,16 +794,35 @@ def std( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.std() + + Dimensions: () + Data variables: + da float64 0.7483 Use ``skipna`` to control whether NaNs are ignored. >>> ds.std(skipna=False) + + Dimensions: () + Data variables: + da float64 nan Specify ``ddof=1`` for an unbiased estimate. >>> ds.std(skipna=True, ddof=1) + + Dimensions: () + Data variables: + da float64 0.8367 """ return self.reduce( duck_array_ops.std, @@ -763,16 +898,35 @@ def var( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.var() + + Dimensions: () + Data variables: + da float64 0.56 Use ``skipna`` to control whether NaNs are ignored. >>> ds.var(skipna=False) + + Dimensions: () + Data variables: + da float64 nan Specify ``ddof=1`` for an unbiased estimate. >>> ds.var(skipna=True, ddof=1) + + Dimensions: () + Data variables: + da float64 0.7 """ return self.reduce( duck_array_ops.var, @@ -844,12 +998,27 @@ def median( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.median() + + Dimensions: () + Data variables: + da float64 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.median(skipna=False) + + Dimensions: () + Data variables: + da float64 nan """ return self.reduce( duck_array_ops.median, @@ -925,8 +1094,15 @@ def count( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.count() + + array(5) """ return self.reduce( duck_array_ops.count, @@ -984,8 +1160,15 @@ def all( ... ), ... ) >>> da + + array([ True, True, True, True, True, False]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.all() + + array(False) """ return self.reduce( duck_array_ops.array_all, @@ -1043,8 +1226,15 @@ def any( ... ), ... ) >>> da + + array([ True, True, True, True, True, False]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.any() + + array(True) """ return self.reduce( duck_array_ops.array_any, @@ -1108,12 +1298,21 @@ def max( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.max() + + array(3.) Use ``skipna`` to control whether NaNs are ignored. >>> da.max(skipna=False) + + array(nan) """ return self.reduce( duck_array_ops.max, @@ -1178,12 +1377,21 @@ def min( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.min() + + array(1.) Use ``skipna`` to control whether NaNs are ignored. >>> da.min(skipna=False) + + array(nan) """ return self.reduce( duck_array_ops.min, @@ -1252,12 +1460,21 @@ def mean( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.mean() + + array(1.8) Use ``skipna`` to control whether NaNs are ignored. >>> da.mean(skipna=False) + + array(nan) """ return self.reduce( duck_array_ops.mean, @@ -1333,16 +1550,27 @@ def prod( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.prod() + + array(12.) Use ``skipna`` to control whether NaNs are ignored. >>> da.prod(skipna=False) + + array(nan) Specify ``min_count`` for finer control over when NaNs are ignored. >>> da.prod(skipna=True, min_count=2) + + array(12.) """ return self.reduce( duck_array_ops.prod, @@ -1419,16 +1647,27 @@ def sum( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.sum() + + array(9.) Use ``skipna`` to control whether NaNs are ignored. >>> da.sum(skipna=False) + + array(nan) Specify ``min_count`` for finer control over when NaNs are ignored. >>> da.sum(skipna=True, min_count=2) + + array(9.) """ return self.reduce( duck_array_ops.sum, @@ -1502,16 +1741,27 @@ def std( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.std() + + array(0.74833148) Use ``skipna`` to control whether NaNs are ignored. >>> da.std(skipna=False) + + array(nan) Specify ``ddof=1`` for an unbiased estimate. >>> da.std(skipna=True, ddof=1) + + array(0.83666003) """ return self.reduce( duck_array_ops.std, @@ -1585,16 +1835,27 @@ def var( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.var() + + array(0.56) Use ``skipna`` to control whether NaNs are ignored. >>> da.var(skipna=False) + + array(nan) Specify ``ddof=1`` for an unbiased estimate. >>> da.var(skipna=True, ddof=1) + + array(0.7) """ return self.reduce( duck_array_ops.var, @@ -1664,12 +1925,21 @@ def median( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.median() + + array(2.) Use ``skipna`` to control whether NaNs are ignored. >>> da.median(skipna=False) + + array(nan) """ return self.reduce( duck_array_ops.median, @@ -1753,8 +2023,21 @@ def count( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.groupby("labels").count() + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) int64 1 2 2 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -1825,8 +2108,21 @@ def all( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.groupby("labels").all() + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) bool False True True """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -1897,8 +2193,21 @@ def any( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.groupby("labels").any() + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) bool True True True """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -1975,12 +2284,31 @@ def max( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.groupby("labels").max() + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 1.0 2.0 3.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").max(skipna=False) + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 nan 2.0 3.0 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2059,12 +2387,31 @@ def min( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.groupby("labels").min() + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 1.0 2.0 1.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").min(skipna=False) + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 nan 2.0 1.0 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2147,12 +2494,31 @@ def mean( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.groupby("labels").mean() + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 1.0 2.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").mean(skipna=False) + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 nan 2.0 2.0 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2242,16 +2608,41 @@ def prod( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.groupby("labels").prod() + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 1.0 4.0 3.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").prod(skipna=False) + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 nan 4.0 3.0 Specify ``min_count`` for finer control over when NaNs are ignored. >>> ds.groupby("labels").prod(skipna=True, min_count=2) + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 nan 4.0 3.0 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2343,16 +2734,41 @@ def sum( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.groupby("labels").sum() + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 1.0 4.0 4.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").sum(skipna=False) + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 nan 4.0 4.0 Specify ``min_count`` for finer control over when NaNs are ignored. >>> ds.groupby("labels").sum(skipna=True, min_count=2) + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 nan 4.0 4.0 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2441,16 +2857,41 @@ def std( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.groupby("labels").std() + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 0.0 0.0 1.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").std(skipna=False) + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 nan 0.0 1.0 Specify ``ddof=1`` for an unbiased estimate. >>> ds.groupby("labels").std(skipna=True, ddof=1) + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 nan 0.0 1.414 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2539,16 +2980,41 @@ def var( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.groupby("labels").var() + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 0.0 0.0 1.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").var(skipna=False) + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 nan 0.0 1.0 Specify ``ddof=1`` for an unbiased estimate. >>> ds.groupby("labels").var(skipna=True, ddof=1) + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 nan 0.0 2.0 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2633,12 +3099,31 @@ def median( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.groupby("labels").median() + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 1.0 2.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.groupby("labels").median(skipna=False) + + Dimensions: (labels: 3) + Coordinates: + * labels (labels) object 'a' 'b' 'c' + Data variables: + da (labels) float64 nan 2.0 2.0 """ return self.reduce( duck_array_ops.median, @@ -2723,8 +3208,21 @@ def count( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.resample(time="3M").count() + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) int64 1 3 1 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2795,8 +3293,21 @@ def all( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.resample(time="3M").all() + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) bool True True False """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2867,8 +3378,21 @@ def any( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.resample(time="3M").any() + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) bool True True True """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -2945,12 +3469,31 @@ def max( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.resample(time="3M").max() + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 1.0 3.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").max(skipna=False) + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 1.0 3.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3029,12 +3572,31 @@ def min( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.resample(time="3M").min() + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 1.0 1.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").min(skipna=False) + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 1.0 1.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3117,12 +3679,31 @@ def mean( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.resample(time="3M").mean() + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 1.0 2.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").mean(skipna=False) + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 1.0 2.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3212,16 +3793,41 @@ def prod( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.resample(time="3M").prod() + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 1.0 6.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").prod(skipna=False) + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 1.0 6.0 nan Specify ``min_count`` for finer control over when NaNs are ignored. >>> ds.resample(time="3M").prod(skipna=True, min_count=2) + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 nan 6.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3313,16 +3919,41 @@ def sum( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.resample(time="3M").sum() + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 1.0 6.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").sum(skipna=False) + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 1.0 6.0 nan Specify ``min_count`` for finer control over when NaNs are ignored. >>> ds.resample(time="3M").sum(skipna=True, min_count=2) + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 nan 6.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3411,16 +4042,41 @@ def std( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.resample(time="3M").std() + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 0.0 0.8165 0.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").std(skipna=False) + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 0.0 0.8165 nan Specify ``ddof=1`` for an unbiased estimate. >>> ds.resample(time="3M").std(skipna=True, ddof=1) + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 nan 1.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3509,16 +4165,41 @@ def var( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.resample(time="3M").var() + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 0.0 0.6667 0.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").var(skipna=False) + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 0.0 0.6667 nan Specify ``ddof=1`` for an unbiased estimate. >>> ds.resample(time="3M").var(skipna=True, ddof=1) + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 nan 1.0 nan """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3603,12 +4284,31 @@ def median( ... ) >>> ds = xr.Dataset(dict(da=da)) >>> ds + + Dimensions: (time: 6) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> ds.resample(time="3M").median() + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 1.0 2.0 2.0 Use ``skipna`` to control whether NaNs are ignored. >>> ds.resample(time="3M").median(skipna=False) + + Dimensions: (time: 3) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 + Data variables: + da (time) float64 1.0 2.0 nan """ return self.reduce( duck_array_ops.median, @@ -3692,8 +4392,17 @@ def count( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.groupby("labels").count() + + array([1, 2, 2], dtype=int64) + Coordinates: + * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3761,8 +4470,17 @@ def all( ... ), ... ) >>> da + + array([ True, True, True, True, True, False]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.groupby("labels").all() + + array([False, True, True]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3830,8 +4548,17 @@ def any( ... ), ... ) >>> da + + array([ True, True, True, True, True, False]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.groupby("labels").any() + + array([ True, True, True]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3905,12 +4632,25 @@ def max( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.groupby("labels").max() + + array([1., 2., 3.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").max(skipna=False) + + array([nan, 2., 3.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -3986,12 +4726,25 @@ def min( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.groupby("labels").min() + + array([1., 2., 1.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").min(skipna=False) + + array([nan, 2., 1.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4071,12 +4824,25 @@ def mean( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.groupby("labels").mean() + + array([1., 2., 2.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").mean(skipna=False) + + array([nan, 2., 2.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4163,16 +4929,33 @@ def prod( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.groupby("labels").prod() + + array([1., 4., 3.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").prod(skipna=False) + + array([nan, 4., 3.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' Specify ``min_count`` for finer control over when NaNs are ignored. >>> da.groupby("labels").prod(skipna=True, min_count=2) + + array([nan, 4., 3.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4261,16 +5044,33 @@ def sum( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.groupby("labels").sum() + + array([1., 4., 4.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").sum(skipna=False) + + array([nan, 4., 4.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' Specify ``min_count`` for finer control over when NaNs are ignored. >>> da.groupby("labels").sum(skipna=True, min_count=2) + + array([nan, 4., 4.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4356,16 +5156,33 @@ def std( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.groupby("labels").std() + + array([0., 0., 1.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").std(skipna=False) + + array([nan, 0., 1.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' Specify ``ddof=1`` for an unbiased estimate. >>> da.groupby("labels").std(skipna=True, ddof=1) + + array([ nan, 0. , 1.41421356]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4451,16 +5268,33 @@ def var( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.groupby("labels").var() + + array([0., 0., 1.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").var(skipna=False) + + array([nan, 0., 1.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' Specify ``ddof=1`` for an unbiased estimate. >>> da.groupby("labels").var(skipna=True, ddof=1) + + array([nan, 0., 2.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4542,12 +5376,25 @@ def median( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.groupby("labels").median() + + array([1., 2., 2.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' Use ``skipna`` to control whether NaNs are ignored. >>> da.groupby("labels").median(skipna=False) + + array([nan, 2., 2.]) + Coordinates: + * labels (labels) object 'a' 'b' 'c' """ return self.reduce( duck_array_ops.median, @@ -4630,8 +5477,17 @@ def count( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.resample(time="3M").count() + + array([1, 3, 1], dtype=int64) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4699,8 +5555,17 @@ def all( ... ), ... ) >>> da + + array([ True, True, True, True, True, False]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.resample(time="3M").all() + + array([ True, True, False]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4768,8 +5633,17 @@ def any( ... ), ... ) >>> da + + array([ True, True, True, True, True, False]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.resample(time="3M").any() + + array([ True, True, True]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4843,12 +5717,25 @@ def max( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.resample(time="3M").max() + + array([1., 3., 2.]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").max(skipna=False) + + array([ 1., 3., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -4924,12 +5811,25 @@ def min( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.resample(time="3M").min() + + array([1., 1., 2.]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").min(skipna=False) + + array([ 1., 1., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5009,12 +5909,25 @@ def mean( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.resample(time="3M").mean() + + array([1., 2., 2.]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").mean(skipna=False) + + array([ 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5101,16 +6014,33 @@ def prod( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.resample(time="3M").prod() + + array([1., 6., 2.]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").prod(skipna=False) + + array([ 1., 6., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Specify ``min_count`` for finer control over when NaNs are ignored. >>> da.resample(time="3M").prod(skipna=True, min_count=2) + + array([nan, 6., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5199,16 +6129,33 @@ def sum( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.resample(time="3M").sum() + + array([1., 6., 2.]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").sum(skipna=False) + + array([ 1., 6., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Specify ``min_count`` for finer control over when NaNs are ignored. >>> da.resample(time="3M").sum(skipna=True, min_count=2) + + array([nan, 6., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5294,16 +6241,33 @@ def std( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.resample(time="3M").std() + + array([0. , 0.81649658, 0. ]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").std(skipna=False) + + array([0. , 0.81649658, nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Specify ``ddof=1`` for an unbiased estimate. >>> da.resample(time="3M").std(skipna=True, ddof=1) + + array([nan, 1., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5389,16 +6353,33 @@ def var( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.resample(time="3M").var() + + array([0. , 0.66666667, 0. ]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").var(skipna=False) + + array([0. , 0.66666667, nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Specify ``ddof=1`` for an unbiased estimate. >>> da.resample(time="3M").var(skipna=True, ddof=1) + + array([nan, 1., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ if flox and OPTIONS["use_flox"] and contains_only_dask_or_numpy(self._obj): return self._flox_reduce( @@ -5480,12 +6461,25 @@ def median( ... ), ... ) >>> da + + array([ 1., 2., 3., 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-02-28 ... 2001-06-30 + labels (time) >> da.resample(time="3M").median() + + array([1., 2., 2.]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 Use ``skipna`` to control whether NaNs are ignored. >>> da.resample(time="3M").median(skipna=False) + + array([ 1., 2., nan]) + Coordinates: + * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ return self.reduce( duck_array_ops.median, From 5fa6255848966b4578cc499e3c9fda8219b1540d Mon Sep 17 00:00:00 2001 From: Michael Niklas Date: Sat, 17 Sep 2022 13:24:49 +0200 Subject: [PATCH 05/11] fix bug in reduce for 1D arrays --- xarray/core/dataset.py | 4 +++- xarray/core/groupby.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 55a3a7f3ed0..0191376a4af 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -5582,7 +5582,9 @@ def reduce( # axis=(0, 1) if they will be equivalent, because # the former is often more efficient reduce_maybe_single = ( - None if len(reduce_dims) == var.ndim else reduce_dims + None + if len(reduce_dims) == var.ndim and var.ndim != 1 + else reduce_dims ) variables[name] = var.reduce( func, diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py index 69c45fbd32c..92feca4e114 100644 --- a/xarray/core/groupby.py +++ b/xarray/core/groupby.py @@ -979,7 +979,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""" From 93bc0a9ea38d5e7ed26b94c2eb6a53ac02074d67 Mon Sep 17 00:00:00 2001 From: Michael Niklas Date: Sat, 17 Sep 2022 16:06:29 +0200 Subject: [PATCH 06/11] use builtin ellipsis type --- xarray/core/_reductions.py | 105 ++++++++++++++--------------- xarray/core/computation.py | 4 +- xarray/core/dataarray.py | 9 ++- xarray/core/dataset.py | 9 ++- xarray/core/groupby.py | 10 +-- xarray/core/resample.py | 6 +- xarray/core/types.py | 3 - xarray/core/variable.py | 11 ++- xarray/core/weighted.py | 4 +- xarray/tests/test_plot.py | 2 +- xarray/util/generate_reductions.py | 11 ++- 11 files changed, 83 insertions(+), 91 deletions(-) diff --git a/xarray/core/_reductions.py b/xarray/core/_reductions.py index e16ebe4c19f..901a455b8d5 100644 --- a/xarray/core/_reductions.py +++ b/xarray/core/_reductions.py @@ -7,7 +7,6 @@ from . import duck_array_ops from .options import OPTIONS -from .types import Ellipsis from .utils import contains_only_dask_or_numpy if TYPE_CHECKING: @@ -1956,7 +1955,7 @@ class DatasetGroupByReductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -1967,14 +1966,14 @@ def reduce( def _flox_reduce( self, - dim: str | Iterable[Hashable] | Ellipsis | None, + dim: str | Iterable[Hashable] | ellipsis | None, **kwargs: Any, ) -> Dataset: raise NotImplementedError() def count( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -2059,7 +2058,7 @@ def count( def all( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -2144,7 +2143,7 @@ def all( def any( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -2229,7 +2228,7 @@ def any( def max( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -2332,7 +2331,7 @@ def max( def min( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -2435,7 +2434,7 @@ def min( def mean( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -2542,7 +2541,7 @@ def mean( def prod( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -2668,7 +2667,7 @@ def prod( def sum( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -2794,7 +2793,7 @@ def sum( def std( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -2917,7 +2916,7 @@ def std( def var( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -3040,7 +3039,7 @@ def var( def median( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3141,7 +3140,7 @@ class DatasetResampleReductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -3152,14 +3151,14 @@ def reduce( def _flox_reduce( self, - dim: str | Iterable[Hashable] | Ellipsis | None, + dim: str | Iterable[Hashable] | ellipsis | None, **kwargs: Any, ) -> Dataset: raise NotImplementedError() def count( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -3244,7 +3243,7 @@ def count( def all( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -3329,7 +3328,7 @@ def all( def any( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -3414,7 +3413,7 @@ def any( def max( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3517,7 +3516,7 @@ def max( def min( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3620,7 +3619,7 @@ def min( def mean( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3727,7 +3726,7 @@ def mean( def prod( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -3853,7 +3852,7 @@ def prod( def sum( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -3979,7 +3978,7 @@ def sum( def std( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -4102,7 +4101,7 @@ def std( def var( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -4225,7 +4224,7 @@ def var( def median( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4326,7 +4325,7 @@ class DataArrayGroupByReductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -4337,14 +4336,14 @@ def reduce( def _flox_reduce( self, - dim: str | Iterable[Hashable] | Ellipsis | None, + dim: str | Iterable[Hashable] | ellipsis | None, **kwargs: Any, ) -> DataArray: raise NotImplementedError() def count( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -4422,7 +4421,7 @@ def count( def all( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -4500,7 +4499,7 @@ def all( def any( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -4578,7 +4577,7 @@ def any( def max( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4672,7 +4671,7 @@ def max( def min( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4766,7 +4765,7 @@ def min( def mean( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4864,7 +4863,7 @@ def mean( def prod( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -4979,7 +4978,7 @@ def prod( def sum( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -5094,7 +5093,7 @@ def sum( def std( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -5206,7 +5205,7 @@ def std( def var( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -5318,7 +5317,7 @@ def var( def median( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5411,7 +5410,7 @@ class DataArrayResampleReductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -5422,14 +5421,14 @@ def reduce( def _flox_reduce( self, - dim: str | Iterable[Hashable] | Ellipsis | None, + dim: str | Iterable[Hashable] | ellipsis | None, **kwargs: Any, ) -> DataArray: raise NotImplementedError() def count( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -5507,7 +5506,7 @@ def count( def all( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -5585,7 +5584,7 @@ def all( def any( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -5663,7 +5662,7 @@ def any( def max( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5757,7 +5756,7 @@ def max( def min( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5851,7 +5850,7 @@ def min( def mean( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5949,7 +5948,7 @@ def mean( def prod( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -6064,7 +6063,7 @@ def prod( def sum( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -6179,7 +6178,7 @@ def sum( def std( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -6291,7 +6290,7 @@ def std( def var( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, ddof: int = 0, @@ -6403,7 +6402,7 @@ def var( def median( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, 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 e4eb7592b1e..bd54a5dbe84 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -78,7 +78,6 @@ from .types import ( CoarsenBoundaryOptions, DatetimeUnitOptions, - Ellipsis, ErrorOptions, ErrorOptionsWithWarn, InterpOptions, @@ -2888,7 +2887,7 @@ def combine_first(self: T_DataArray, other: T_DataArray) -> T_DataArray: def reduce( self: T_DataArray, func: Callable[..., Any], - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -3771,7 +3770,7 @@ def imag(self: T_DataArray) -> T_DataArray: def dot( self: T_DataArray, other: T_DataArray, - dims: str | Iterable[Hashable] | Ellipsis | None = None, + dims: str | Iterable[Hashable] | ellipsis | None = None, ) -> T_DataArray: """Perform dot product of two DataArrays along their shared dims. @@ -4775,7 +4774,7 @@ def idxmax( # https://github.com/python/mypy/issues/12846 is resolved def argmin( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, axis: int | None = None, keep_attrs: bool | None = None, skipna: bool | None = None, @@ -4880,7 +4879,7 @@ def argmin( # https://github.com/python/mypy/issues/12846 is resolved def argmax( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, axis: int | None = None, keep_attrs: bool | None = None, skipna: bool | None = None, diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 0191376a4af..309670301d0 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -107,7 +107,6 @@ CombineAttrsOptions, CompatOptions, DatetimeUnitOptions, - Ellipsis, ErrorOptions, ErrorOptionsWithWarn, InterpOptions, @@ -4256,7 +4255,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 +4314,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. @@ -5504,7 +5503,7 @@ def combine_first(self: T_Dataset, other: T_Dataset) -> T_Dataset: def reduce( self: T_Dataset, func: Callable, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, keep_attrs: bool | None = None, keepdims: bool = False, diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py index 92feca4e114..6731c3600c8 100644 --- a/xarray/core/groupby.py +++ b/xarray/core/groupby.py @@ -33,7 +33,7 @@ from .ops import IncludeCumMethods from .options import _get_keep_attrs from .pycompat import integer_types -from .types import Ellipsis, T_Xarray +from .types import T_Xarray from .utils import ( either_dict_or_kwargs, hashable, @@ -496,7 +496,7 @@ def map( def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -655,7 +655,7 @@ def _maybe_unstack(self, obj): def _flox_reduce( self, - dim: str | Iterable[Hashable] | Ellipsis | None, + dim: str | Iterable[Hashable] | ellipsis | None, keep_attrs: bool | None = None, **kwargs: Any, ): @@ -1149,7 +1149,7 @@ def _combine(self, applied, shortcut=False): def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -1300,7 +1300,7 @@ def _combine(self, applied): def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, diff --git a/xarray/core/resample.py b/xarray/core/resample.py index f1c7f4fbe83..7fc622917b3 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 Ellipsis, InterpOptions, T_Xarray +from .types import InterpOptions, T_Xarray if TYPE_CHECKING: from .dataarray import DataArray @@ -50,7 +50,7 @@ def __init__( def _flox_reduce( self, - dim: str | Iterable[Hashable] | Ellipsis | None, + dim: str | Iterable[Hashable] | ellipsis | None, keep_attrs: bool | None = None, **kwargs, ) -> T_Xarray: @@ -360,7 +360,7 @@ def apply(self, func, args=(), shortcut=None, **kwargs): def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, diff --git a/xarray/core/types.py b/xarray/core/types.py index 8a75572522a..2f2cbb10456 100644 --- a/xarray/core/types.py +++ b/xarray/core/types.py @@ -32,11 +32,8 @@ # Self: Any = None Self = TypeVar("Self") - Ellipsis = ellipsis - else: Self: Any = None - Ellipsis: Any = None T_Dataset = TypeVar("T_Dataset", bound="Dataset") diff --git a/xarray/core/variable.py b/xarray/core/variable.py index 537643ea187..fc02469acbc 100644 --- a/xarray/core/variable.py +++ b/xarray/core/variable.py @@ -71,7 +71,6 @@ if TYPE_CHECKING: from .types import ( - Ellipsis, ErrorOptionsWithWarn, PadModeOptions, PadReflectOptions, @@ -1479,7 +1478,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. @@ -1801,7 +1800,7 @@ def clip(self, min=None, max=None): def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, @@ -2561,7 +2560,7 @@ def _to_numeric(self, offset=None, datetime_unit=None, dtype=float): def _unravel_argminmax( self, argminmax: str, - dim: str | Iterable[Hashable] | Ellipsis | None, + dim: str | Iterable[Hashable] | ellipsis | None, axis: int | None, keep_attrs: bool | None, skipna: bool | None, @@ -2630,7 +2629,7 @@ def _unravel_argminmax( def argmin( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, axis: int = None, keep_attrs: bool = None, skipna: bool = None, @@ -2675,7 +2674,7 @@ def argmin( def argmax( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, axis: int = None, keep_attrs: bool = None, skipna: bool = None, diff --git a/xarray/core/weighted.py b/xarray/core/weighted.py index 9d5be6f7126..9765051c0cd 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 T_Xarray # Weighted quantile methods are a subset of the numpy supported quantile methods. QUANTILE_METHODS = Literal[ @@ -206,7 +206,7 @@ def _check_dim(self, dim: Hashable | Iterable[Hashable] | None): def _reduce( da: DataArray, weights: DataArray, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, skipna: bool | None = None, ) -> DataArray: """reduce using dot; equivalent to (da * weights).sum(dim, skipna) 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 2ef64308677..747fec1b4d7 100644 --- a/xarray/util/generate_reductions.py +++ b/xarray/util/generate_reductions.py @@ -26,7 +26,6 @@ from . import duck_array_ops from .options import OPTIONS -from .types import Ellipsis from .utils import contains_only_dask_or_numpy if TYPE_CHECKING: @@ -63,7 +62,7 @@ class {obj}{cls}Reductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -74,7 +73,7 @@ def reduce( def _flox_reduce( self, - dim: str | Iterable[Hashable] | Ellipsis | None, + dim: str | Iterable[Hashable] | ellipsis | None, **kwargs: Any, ) -> {obj}: raise NotImplementedError()""" @@ -87,7 +86,7 @@ class {obj}{cls}Reductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -98,7 +97,7 @@ def reduce( def _flox_reduce( self, - dim: str | Iterable[Hashable] | Ellipsis | None, + dim: str | Iterable[Hashable] | ellipsis | None, **kwargs: Any, ) -> {obj}: raise NotImplementedError()""" @@ -120,7 +119,7 @@ def {method}( TEMPLATE_REDUCTION_SIGNATURE_GROUPBY = ''' def {method}( self, - dim: str | Iterable[Hashable] | Ellipsis | None = None, + dim: str | Iterable[Hashable] | ellipsis | None = None, *,{extra_kwargs} keep_attrs: bool | None = None, **kwargs: Any, From 70a57566b7b3d79b7f45bfff772305ac52f7343a Mon Sep 17 00:00:00 2001 From: Michael Niklas Date: Sat, 17 Sep 2022 16:14:46 +0200 Subject: [PATCH 07/11] add Dims type --- xarray/core/_reductions.py | 149 +++++++++++++++-------------- xarray/core/dataarray.py | 3 +- xarray/core/dataset.py | 3 +- xarray/core/groupby.py | 4 +- xarray/core/types.py | 14 ++- xarray/core/weighted.py | 16 ++-- xarray/util/generate_reductions.py | 13 +-- 7 files changed, 108 insertions(+), 94 deletions(-) diff --git a/xarray/core/_reductions.py b/xarray/core/_reductions.py index 901a455b8d5..78ae841e669 100644 --- a/xarray/core/_reductions.py +++ b/xarray/core/_reductions.py @@ -7,6 +7,7 @@ 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,7 +26,7 @@ class DatasetReductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -36,7 +37,7 @@ def reduce( def count( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -108,7 +109,7 @@ def count( def all( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -180,7 +181,7 @@ def all( def any( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -252,7 +253,7 @@ def any( def max( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -339,7 +340,7 @@ def max( def min( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -426,7 +427,7 @@ def min( def mean( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -517,7 +518,7 @@ def mean( def prod( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -624,7 +625,7 @@ def prod( def sum( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -731,7 +732,7 @@ def sum( def std( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, ddof: int = 0, @@ -835,7 +836,7 @@ def std( def var( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, ddof: int = 0, @@ -939,7 +940,7 @@ def var( def median( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1035,7 +1036,7 @@ class DataArrayReductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -1046,7 +1047,7 @@ def reduce( def count( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -1112,7 +1113,7 @@ def count( def all( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -1178,7 +1179,7 @@ def all( def any( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -1244,7 +1245,7 @@ def any( def max( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1323,7 +1324,7 @@ def max( def min( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1402,7 +1403,7 @@ def min( def mean( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1485,7 +1486,7 @@ def mean( def prod( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -1582,7 +1583,7 @@ def prod( def sum( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -1679,7 +1680,7 @@ def sum( def std( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, ddof: int = 0, @@ -1773,7 +1774,7 @@ def std( def var( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, ddof: int = 0, @@ -1867,7 +1868,7 @@ def var( def median( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -1955,7 +1956,7 @@ class DatasetGroupByReductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -1973,7 +1974,7 @@ def _flox_reduce( def count( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -2058,7 +2059,7 @@ def count( def all( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -2143,7 +2144,7 @@ def all( def any( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -2228,7 +2229,7 @@ def any( def max( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -2331,7 +2332,7 @@ def max( def min( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -2434,7 +2435,7 @@ def min( def mean( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -2541,7 +2542,7 @@ def mean( def prod( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -2667,7 +2668,7 @@ def prod( def sum( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -2793,7 +2794,7 @@ def sum( def std( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -2916,7 +2917,7 @@ def std( def var( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -3039,7 +3040,7 @@ def var( def median( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3140,7 +3141,7 @@ class DatasetResampleReductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -3151,14 +3152,14 @@ def reduce( def _flox_reduce( self, - dim: str | Iterable[Hashable] | ellipsis | None, + dim: Dims | ellipsis, **kwargs: Any, ) -> Dataset: raise NotImplementedError() def count( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -3243,7 +3244,7 @@ def count( def all( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -3328,7 +3329,7 @@ def all( def any( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -3413,7 +3414,7 @@ def any( def max( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3516,7 +3517,7 @@ def max( def min( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3619,7 +3620,7 @@ def min( def mean( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -3726,7 +3727,7 @@ def mean( def prod( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -3852,7 +3853,7 @@ def prod( def sum( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -3978,7 +3979,7 @@ def sum( def std( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -4101,7 +4102,7 @@ def std( def var( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -4224,7 +4225,7 @@ def var( def median( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4325,7 +4326,7 @@ class DataArrayGroupByReductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -4343,7 +4344,7 @@ def _flox_reduce( def count( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -4421,7 +4422,7 @@ def count( def all( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -4499,7 +4500,7 @@ def all( def any( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -4577,7 +4578,7 @@ def any( def max( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4671,7 +4672,7 @@ def max( def min( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4765,7 +4766,7 @@ def min( def mean( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -4863,7 +4864,7 @@ def mean( def prod( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -4978,7 +4979,7 @@ def prod( def sum( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -5093,7 +5094,7 @@ def sum( def std( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -5205,7 +5206,7 @@ def std( def var( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -5317,7 +5318,7 @@ def var( def median( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5410,7 +5411,7 @@ class DataArrayResampleReductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -5421,14 +5422,14 @@ def reduce( def _flox_reduce( self, - dim: str | Iterable[Hashable] | ellipsis | None, + dim: Dims | ellipsis, **kwargs: Any, ) -> DataArray: raise NotImplementedError() def count( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -5506,7 +5507,7 @@ def count( def all( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -5584,7 +5585,7 @@ def all( def any( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, **kwargs: Any, @@ -5662,7 +5663,7 @@ def any( def max( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5756,7 +5757,7 @@ def max( def min( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5850,7 +5851,7 @@ def min( def mean( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, @@ -5948,7 +5949,7 @@ def mean( def prod( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -6063,7 +6064,7 @@ def prod( def sum( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, min_count: int | None = None, @@ -6178,7 +6179,7 @@ def sum( def std( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -6290,7 +6291,7 @@ def std( def var( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, ddof: int = 0, @@ -6402,7 +6403,7 @@ def var( def median( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, skipna: bool | None = None, keep_attrs: bool | None = None, diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index bd54a5dbe84..c53135aaa18 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -78,6 +78,7 @@ from .types import ( CoarsenBoundaryOptions, DatetimeUnitOptions, + Dims, ErrorOptions, ErrorOptionsWithWarn, InterpOptions, @@ -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, diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index 309670301d0..49ec39dea27 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -107,6 +107,7 @@ CombineAttrsOptions, CompatOptions, DatetimeUnitOptions, + Dims, ErrorOptions, ErrorOptionsWithWarn, InterpOptions, @@ -6693,7 +6694,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, diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py index 8e0672d48ce..02232f992db 100644 --- a/xarray/core/groupby.py +++ b/xarray/core/groupby.py @@ -33,7 +33,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, @@ -814,7 +814,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, diff --git a/xarray/core/types.py b/xarray/core/types.py index 59c0dad21fb..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 @@ -54,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/weighted.py b/xarray/core/weighted.py index 9765051c0cd..4788aeb4f1a 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 T_Xarray +from .types import Dims, T_Xarray # Weighted quantile methods are a subset of the numpy supported quantile methods. QUANTILE_METHODS = Literal[ @@ -226,9 +226,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 +249,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 +261,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 +271,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 +285,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 +299,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).""" diff --git a/xarray/util/generate_reductions.py b/xarray/util/generate_reductions.py index 747fec1b4d7..a6a4e2ec888 100644 --- a/xarray/util/generate_reductions.py +++ b/xarray/util/generate_reductions.py @@ -26,6 +26,7 @@ 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,7 +46,7 @@ class {obj}{cls}Reductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -62,7 +63,7 @@ class {obj}{cls}Reductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -86,7 +87,7 @@ class {obj}{cls}Reductions: def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -97,7 +98,7 @@ def reduce( def _flox_reduce( self, - dim: str | Iterable[Hashable] | ellipsis | None, + dim: Dims | ellipsis, **kwargs: Any, ) -> {obj}: raise NotImplementedError()""" @@ -105,7 +106,7 @@ def _flox_reduce( TEMPLATE_REDUCTION_SIGNATURE = ''' def {method}( self, - dim: str | Iterable[Hashable] | None = None, + dim: Dims = None, *,{extra_kwargs} keep_attrs: bool | None = None, **kwargs: Any, @@ -119,7 +120,7 @@ def {method}( TEMPLATE_REDUCTION_SIGNATURE_GROUPBY = ''' def {method}( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *,{extra_kwargs} keep_attrs: bool | None = None, **kwargs: Any, From a143e6d25ddfc05bc036d55b0da57453c3ebd660 Mon Sep 17 00:00:00 2001 From: Michael Niklas Date: Sat, 17 Sep 2022 16:18:54 +0200 Subject: [PATCH 08/11] add forgotten Dims type --- xarray/core/_reductions.py | 6 +++--- xarray/util/generate_reductions.py | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/xarray/core/_reductions.py b/xarray/core/_reductions.py index 78ae841e669..a7cf7ec2c53 100644 --- a/xarray/core/_reductions.py +++ b/xarray/core/_reductions.py @@ -3,7 +3,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Hashable, Iterable, Sequence +from typing import TYPE_CHECKING, Any, Callable, Sequence from . import duck_array_ops from .options import OPTIONS @@ -1967,7 +1967,7 @@ def reduce( def _flox_reduce( self, - dim: str | Iterable[Hashable] | ellipsis | None, + dim: Dims | ellipsis, **kwargs: Any, ) -> Dataset: raise NotImplementedError() @@ -4337,7 +4337,7 @@ def reduce( def _flox_reduce( self, - dim: str | Iterable[Hashable] | ellipsis | None, + dim: Dims | ellipsis, **kwargs: Any, ) -> DataArray: raise NotImplementedError() diff --git a/xarray/util/generate_reductions.py b/xarray/util/generate_reductions.py index a6a4e2ec888..92e9cc341c9 100644 --- a/xarray/util/generate_reductions.py +++ b/xarray/util/generate_reductions.py @@ -22,7 +22,7 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any, Callable, Hashable, Iterable, Sequence +from typing import TYPE_CHECKING, Any, Callable, Sequence from . import duck_array_ops from .options import OPTIONS @@ -74,7 +74,7 @@ def reduce( def _flox_reduce( self, - dim: str | Iterable[Hashable] | ellipsis | None, + dim: Dims | ellipsis, **kwargs: Any, ) -> {obj}: raise NotImplementedError()""" From 1aa578e9bf306d0d2b4039ee389f3557f6735ad5 Mon Sep 17 00:00:00 2001 From: Michael Niklas Date: Sat, 17 Sep 2022 23:08:40 +0200 Subject: [PATCH 09/11] update docstring examples to fit to linux --- xarray/core/_reductions.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/xarray/core/_reductions.py b/xarray/core/_reductions.py index a7cf7ec2c53..d0c2a9d721d 100644 --- a/xarray/core/_reductions.py +++ b/xarray/core/_reductions.py @@ -97,7 +97,7 @@ def count( Dimensions: () Data variables: - da int32 5 + da int64 5 """ return self.reduce( duck_array_ops.count, @@ -4400,7 +4400,7 @@ def count( >>> da.groupby("labels").count() - array([1, 2, 2], dtype=int64) + array([1, 2, 2]) Coordinates: * labels (labels) object 'a' 'b' 'c' """ @@ -5485,7 +5485,7 @@ def count( >>> da.resample(time="3M").count() - array([1, 3, 1], dtype=int64) + array([1, 3, 1]) Coordinates: * time (time) datetime64[ns] 2001-01-31 2001-04-30 2001-07-31 """ From f563fbda141cfa1d53725cb782e05b9df6d2e73c Mon Sep 17 00:00:00 2001 From: Michael Niklas Date: Sun, 18 Sep 2022 14:14:55 +0200 Subject: [PATCH 10/11] replace more instances with Dims type --- xarray/core/dataarray.py | 26 +++++++++++++------------- xarray/core/dataset.py | 27 +++++++++++++-------------- xarray/core/variable.py | 9 +++++---- xarray/core/weighted.py | 21 +++++++++++---------- xarray/tests/test_dataset.py | 5 +++-- 5 files changed, 45 insertions(+), 43 deletions(-) diff --git a/xarray/core/dataarray.py b/xarray/core/dataarray.py index c53135aaa18..c08a30263b4 100644 --- a/xarray/core/dataarray.py +++ b/xarray/core/dataarray.py @@ -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,7 +2888,7 @@ def combine_first(self: T_DataArray, other: T_DataArray) -> T_DataArray: def reduce( self: T_DataArray, func: Callable[..., Any], - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -3771,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. @@ -3781,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. @@ -4775,7 +4775,7 @@ def idxmax( # https://github.com/python/mypy/issues/12846 is resolved def argmin( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, axis: int | None = None, keep_attrs: bool | None = None, skipna: bool | None = None, @@ -4880,7 +4880,7 @@ def argmin( # https://github.com/python/mypy/issues/12846 is resolved def argmax( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, axis: int | None = None, keep_attrs: bool | None = None, skipna: bool | None = None, @@ -5064,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, @@ -5089,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 49ec39dea27..b0fa0761ce4 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -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 @@ -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: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, keep_attrs: bool | None = None, keepdims: bool = False, @@ -8196,7 +8194,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 +8219,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 +8270,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/variable.py b/xarray/core/variable.py index e78842fba74..058bbb129cd 100644 --- a/xarray/core/variable.py +++ b/xarray/core/variable.py @@ -66,6 +66,7 @@ if TYPE_CHECKING: from .types import ( + Dims, ErrorOptionsWithWarn, PadModeOptions, PadReflectOptions, @@ -1795,7 +1796,7 @@ def clip(self, min=None, max=None): def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, keepdims: bool = False, @@ -2555,7 +2556,7 @@ def _to_numeric(self, offset=None, datetime_unit=None, dtype=float): def _unravel_argminmax( self, argminmax: str, - dim: str | Iterable[Hashable] | ellipsis | None, + dim: Dims | ellipsis, axis: int | None, keep_attrs: bool | None, skipna: bool | None, @@ -2624,7 +2625,7 @@ def _unravel_argminmax( def argmin( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, axis: int = None, keep_attrs: bool = None, skipna: bool = None, @@ -2669,7 +2670,7 @@ def argmin( def argmax( self, - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, axis: int = None, keep_attrs: bool = None, skipna: bool = None, diff --git a/xarray/core/weighted.py b/xarray/core/weighted.py index 4788aeb4f1a..a89b29723b4 100644 --- a/xarray/core/weighted.py +++ b/xarray/core/weighted.py @@ -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) @@ -310,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).""" @@ -447,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: @@ -457,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: @@ -468,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: @@ -479,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: @@ -490,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: @@ -501,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: @@ -514,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_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): From f0af587656abbd42a14a2574e207502dbb5e7604 Mon Sep 17 00:00:00 2001 From: Michael Niklas Date: Sun, 18 Sep 2022 14:29:52 +0200 Subject: [PATCH 11/11] replace some leftovers with Dims --- xarray/core/dataset.py | 1 + xarray/core/groupby.py | 9 ++++----- xarray/core/resample.py | 6 +++--- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/xarray/core/dataset.py b/xarray/core/dataset.py index b0fa0761ce4..a7c4e1997b6 100644 --- a/xarray/core/dataset.py +++ b/xarray/core/dataset.py @@ -5579,6 +5579,7 @@ def reduce( # 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 diff --git a/xarray/core/groupby.py b/xarray/core/groupby.py index 02232f992db..8a21406be2b 100644 --- a/xarray/core/groupby.py +++ b/xarray/core/groupby.py @@ -8,7 +8,6 @@ Callable, Generic, Hashable, - Iterable, Iterator, Literal, Mapping, @@ -496,7 +495,7 @@ def map( def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -655,7 +654,7 @@ def _maybe_unstack(self, obj): def _flox_reduce( self, - dim: str | Iterable[Hashable] | ellipsis | None, + dim: Dims | ellipsis, keep_attrs: bool | None = None, **kwargs: Any, ): @@ -1149,7 +1148,7 @@ def _combine(self, applied, shortcut=False): def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, @@ -1303,7 +1302,7 @@ def _combine(self, applied): def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None, diff --git a/xarray/core/resample.py b/xarray/core/resample.py index 7fc622917b3..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 @@ -50,7 +50,7 @@ def __init__( def _flox_reduce( self, - dim: str | Iterable[Hashable] | ellipsis | None, + dim: Dims | ellipsis, keep_attrs: bool | None = None, **kwargs, ) -> T_Xarray: @@ -360,7 +360,7 @@ def apply(self, func, args=(), shortcut=None, **kwargs): def reduce( self, func: Callable[..., Any], - dim: str | Iterable[Hashable] | ellipsis | None = None, + dim: Dims | ellipsis = None, *, axis: int | Sequence[int] | None = None, keep_attrs: bool | None = None,