diff --git a/xarray/core/_aggregations.py b/xarray/core/_aggregations.py index 9ba695a74b4..89cec94e24f 100644 --- a/xarray/core/_aggregations.py +++ b/xarray/core/_aggregations.py @@ -8150,1024 +8150,3 @@ def cumprod( keep_attrs=keep_attrs, **kwargs, ) - - -class VariableAggregations: - __slots__ = () - - def reduce( - self, - func: Callable[..., Any], - dim: Dims = None, - *, - axis: int | Sequence[int] | None = None, - keep_attrs: bool | None = None, - keepdims: bool = False, - **kwargs: Any, - ) -> Self: - raise NotImplementedError() - - def count( - self, - dim: Dims = None, - *, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``count`` along some dimension(s). - - Parameters - ---------- - 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 "..." or None, 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``count`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``count`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - pandas.DataFrame.count - dask.dataframe.DataFrame.count - Dataset.count - DataArray.count - :ref:`agg` - User guide on reduction or aggregation operations. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([1, 2, 3, 0, 2, np.nan]), - ... ) - >>> variable - - array([ 1., 2., 3., 0., 2., nan]) - - >>> variable.count() - - array(5) - """ - return self.reduce( - duck_array_ops.count, - dim=dim, - keep_attrs=keep_attrs, - **kwargs, - ) - - def all( - self, - dim: Dims = None, - *, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``all`` along some dimension(s). - - Parameters - ---------- - 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 "..." or None, 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``all`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``all`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - numpy.all - dask.array.all - Dataset.all - DataArray.all - :ref:`agg` - User guide on reduction or aggregation operations. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([True, True, True, True, True, False], dtype=bool), - ... ) - >>> variable - - array([ True, True, True, True, True, False]) - - >>> variable.all() - - array(False) - """ - return self.reduce( - duck_array_ops.array_all, - dim=dim, - keep_attrs=keep_attrs, - **kwargs, - ) - - def any( - self, - dim: Dims = None, - *, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``any`` along some dimension(s). - - Parameters - ---------- - 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 "..." or None, 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``any`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``any`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - numpy.any - dask.array.any - Dataset.any - DataArray.any - :ref:`agg` - User guide on reduction or aggregation operations. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([True, True, True, True, True, False], dtype=bool), - ... ) - >>> variable - - array([ True, True, True, True, True, False]) - - >>> variable.any() - - array(True) - """ - return self.reduce( - duck_array_ops.array_any, - dim=dim, - keep_attrs=keep_attrs, - **kwargs, - ) - - def max( - self, - dim: Dims = None, - *, - skipna: bool | None = None, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``max`` along some dimension(s). - - Parameters - ---------- - 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 "..." or None, 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 - have a sentinel missing value (int) or ``skipna=True`` has not been - implemented (object, datetime64 or timedelta64). - 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``max`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``max`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - numpy.max - dask.array.max - Dataset.max - DataArray.max - :ref:`agg` - User guide on reduction or aggregation operations. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([1, 2, 3, 0, 2, np.nan]), - ... ) - >>> variable - - array([ 1., 2., 3., 0., 2., nan]) - - >>> variable.max() - - array(3.) - - Use ``skipna`` to control whether NaNs are ignored. - - >>> variable.max(skipna=False) - - array(nan) - """ - return self.reduce( - duck_array_ops.max, - dim=dim, - skipna=skipna, - keep_attrs=keep_attrs, - **kwargs, - ) - - def min( - self, - dim: Dims = None, - *, - skipna: bool | None = None, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``min`` along some dimension(s). - - Parameters - ---------- - 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 "..." or None, 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 - have a sentinel missing value (int) or ``skipna=True`` has not been - implemented (object, datetime64 or timedelta64). - 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``min`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``min`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - numpy.min - dask.array.min - Dataset.min - DataArray.min - :ref:`agg` - User guide on reduction or aggregation operations. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([1, 2, 3, 0, 2, np.nan]), - ... ) - >>> variable - - array([ 1., 2., 3., 0., 2., nan]) - - >>> variable.min() - - array(0.) - - Use ``skipna`` to control whether NaNs are ignored. - - >>> variable.min(skipna=False) - - array(nan) - """ - return self.reduce( - duck_array_ops.min, - dim=dim, - skipna=skipna, - keep_attrs=keep_attrs, - **kwargs, - ) - - def mean( - self, - dim: Dims = None, - *, - skipna: bool | None = None, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``mean`` along some dimension(s). - - Parameters - ---------- - 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 "..." or None, 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 - have a sentinel missing value (int) or ``skipna=True`` has not been - implemented (object, datetime64 or timedelta64). - 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``mean`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``mean`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - numpy.mean - dask.array.mean - Dataset.mean - DataArray.mean - :ref:`agg` - User guide on reduction or aggregation operations. - - Notes - ----- - Non-numeric variables will be removed prior to reducing. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([1, 2, 3, 0, 2, np.nan]), - ... ) - >>> variable - - array([ 1., 2., 3., 0., 2., nan]) - - >>> variable.mean() - - array(1.6) - - Use ``skipna`` to control whether NaNs are ignored. - - >>> variable.mean(skipna=False) - - array(nan) - """ - return self.reduce( - duck_array_ops.mean, - dim=dim, - skipna=skipna, - keep_attrs=keep_attrs, - **kwargs, - ) - - def prod( - self, - dim: Dims = None, - *, - skipna: bool | None = None, - min_count: int | None = None, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``prod`` along some dimension(s). - - Parameters - ---------- - 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 "..." or None, 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 - have a sentinel missing value (int) or ``skipna=True`` has not been - implemented (object, datetime64 or timedelta64). - min_count : int or None, optional - The required number of valid values to perform the operation. If - fewer than min_count non-NA values are present the result will be - NA. Only used if skipna is set to True or defaults to True for the - array's dtype. Changed in version 0.17.0: if specified on an integer - array and skipna=True, the result will be a float array. - 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``prod`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``prod`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - numpy.prod - dask.array.prod - Dataset.prod - DataArray.prod - :ref:`agg` - User guide on reduction or aggregation operations. - - Notes - ----- - Non-numeric variables will be removed prior to reducing. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([1, 2, 3, 0, 2, np.nan]), - ... ) - >>> variable - - array([ 1., 2., 3., 0., 2., nan]) - - >>> variable.prod() - - array(0.) - - Use ``skipna`` to control whether NaNs are ignored. - - >>> variable.prod(skipna=False) - - array(nan) - - Specify ``min_count`` for finer control over when NaNs are ignored. - - >>> variable.prod(skipna=True, min_count=2) - - array(0.) - """ - return self.reduce( - duck_array_ops.prod, - dim=dim, - skipna=skipna, - min_count=min_count, - keep_attrs=keep_attrs, - **kwargs, - ) - - def sum( - self, - dim: Dims = None, - *, - skipna: bool | None = None, - min_count: int | None = None, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``sum`` along some dimension(s). - - Parameters - ---------- - 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 "..." or None, 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 - have a sentinel missing value (int) or ``skipna=True`` has not been - implemented (object, datetime64 or timedelta64). - min_count : int or None, optional - The required number of valid values to perform the operation. If - fewer than min_count non-NA values are present the result will be - NA. Only used if skipna is set to True or defaults to True for the - array's dtype. Changed in version 0.17.0: if specified on an integer - array and skipna=True, the result will be a float array. - 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``sum`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``sum`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - numpy.sum - dask.array.sum - Dataset.sum - DataArray.sum - :ref:`agg` - User guide on reduction or aggregation operations. - - Notes - ----- - Non-numeric variables will be removed prior to reducing. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([1, 2, 3, 0, 2, np.nan]), - ... ) - >>> variable - - array([ 1., 2., 3., 0., 2., nan]) - - >>> variable.sum() - - array(8.) - - Use ``skipna`` to control whether NaNs are ignored. - - >>> variable.sum(skipna=False) - - array(nan) - - Specify ``min_count`` for finer control over when NaNs are ignored. - - >>> variable.sum(skipna=True, min_count=2) - - array(8.) - """ - return self.reduce( - duck_array_ops.sum, - dim=dim, - skipna=skipna, - min_count=min_count, - keep_attrs=keep_attrs, - **kwargs, - ) - - def std( - self, - dim: Dims = None, - *, - skipna: bool | None = None, - ddof: int = 0, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``std`` along some dimension(s). - - Parameters - ---------- - 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 "..." or None, 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 - have a sentinel missing value (int) or ``skipna=True`` has not been - implemented (object, datetime64 or timedelta64). - ddof : int, default: 0 - “Delta Degrees of Freedom”: the divisor used in the calculation is ``N - ddof``, - where ``N`` represents the number of elements. - 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``std`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``std`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - numpy.std - dask.array.std - Dataset.std - DataArray.std - :ref:`agg` - User guide on reduction or aggregation operations. - - Notes - ----- - Non-numeric variables will be removed prior to reducing. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([1, 2, 3, 0, 2, np.nan]), - ... ) - >>> variable - - array([ 1., 2., 3., 0., 2., nan]) - - >>> variable.std() - - array(1.0198039) - - Use ``skipna`` to control whether NaNs are ignored. - - >>> variable.std(skipna=False) - - array(nan) - - Specify ``ddof=1`` for an unbiased estimate. - - >>> variable.std(skipna=True, ddof=1) - - array(1.14017543) - """ - return self.reduce( - duck_array_ops.std, - dim=dim, - skipna=skipna, - ddof=ddof, - keep_attrs=keep_attrs, - **kwargs, - ) - - def var( - self, - dim: Dims = None, - *, - skipna: bool | None = None, - ddof: int = 0, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``var`` along some dimension(s). - - Parameters - ---------- - 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 "..." or None, 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 - have a sentinel missing value (int) or ``skipna=True`` has not been - implemented (object, datetime64 or timedelta64). - ddof : int, default: 0 - “Delta Degrees of Freedom”: the divisor used in the calculation is ``N - ddof``, - where ``N`` represents the number of elements. - 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``var`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``var`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - numpy.var - dask.array.var - Dataset.var - DataArray.var - :ref:`agg` - User guide on reduction or aggregation operations. - - Notes - ----- - Non-numeric variables will be removed prior to reducing. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([1, 2, 3, 0, 2, np.nan]), - ... ) - >>> variable - - array([ 1., 2., 3., 0., 2., nan]) - - >>> variable.var() - - array(1.04) - - Use ``skipna`` to control whether NaNs are ignored. - - >>> variable.var(skipna=False) - - array(nan) - - Specify ``ddof=1`` for an unbiased estimate. - - >>> variable.var(skipna=True, ddof=1) - - array(1.3) - """ - return self.reduce( - duck_array_ops.var, - dim=dim, - skipna=skipna, - ddof=ddof, - keep_attrs=keep_attrs, - **kwargs, - ) - - def median( - self, - dim: Dims = None, - *, - skipna: bool | None = None, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``median`` along some dimension(s). - - Parameters - ---------- - 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 "..." or None, 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 - have a sentinel missing value (int) or ``skipna=True`` has not been - implemented (object, datetime64 or timedelta64). - 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``median`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``median`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - numpy.median - dask.array.median - Dataset.median - DataArray.median - :ref:`agg` - User guide on reduction or aggregation operations. - - Notes - ----- - Non-numeric variables will be removed prior to reducing. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([1, 2, 3, 0, 2, np.nan]), - ... ) - >>> variable - - array([ 1., 2., 3., 0., 2., nan]) - - >>> variable.median() - - array(2.) - - Use ``skipna`` to control whether NaNs are ignored. - - >>> variable.median(skipna=False) - - array(nan) - """ - return self.reduce( - duck_array_ops.median, - dim=dim, - skipna=skipna, - keep_attrs=keep_attrs, - **kwargs, - ) - - def cumsum( - self, - dim: Dims = None, - *, - skipna: bool | None = None, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``cumsum`` along some dimension(s). - - Parameters - ---------- - dim : str, Iterable of Hashable, "..." or None, default: None - Name of dimension[s] along which to apply ``cumsum``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If "..." or None, 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 - have a sentinel missing value (int) or ``skipna=True`` has not been - implemented (object, datetime64 or timedelta64). - 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``cumsum`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``cumsum`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - numpy.cumsum - dask.array.cumsum - Dataset.cumsum - DataArray.cumsum - :ref:`agg` - User guide on reduction or aggregation operations. - - Notes - ----- - Non-numeric variables will be removed prior to reducing. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([1, 2, 3, 0, 2, np.nan]), - ... ) - >>> variable - - array([ 1., 2., 3., 0., 2., nan]) - - >>> variable.cumsum() - - array([1., 3., 6., 6., 8., 8.]) - - Use ``skipna`` to control whether NaNs are ignored. - - >>> variable.cumsum(skipna=False) - - array([ 1., 3., 6., 6., 8., nan]) - """ - return self.reduce( - duck_array_ops.cumsum, - dim=dim, - skipna=skipna, - keep_attrs=keep_attrs, - **kwargs, - ) - - def cumprod( - self, - dim: Dims = None, - *, - skipna: bool | None = None, - keep_attrs: bool | None = None, - **kwargs: Any, - ) -> Self: - """ - Reduce this Variable's data by applying ``cumprod`` along some dimension(s). - - Parameters - ---------- - dim : str, Iterable of Hashable, "..." or None, default: None - Name of dimension[s] along which to apply ``cumprod``. For e.g. ``dim="x"`` - or ``dim=["x", "y"]``. If "..." or None, 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 - have a sentinel missing value (int) or ``skipna=True`` has not been - implemented (object, datetime64 or timedelta64). - 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 - returned without attributes. - **kwargs : Any - Additional keyword arguments passed on to the appropriate array - function for calculating ``cumprod`` on this object's data. - These could include dask-specific kwargs like ``split_every``. - - Returns - ------- - reduced : Variable - New Variable with ``cumprod`` applied to its data and the - indicated dimension(s) removed - - See Also - -------- - numpy.cumprod - dask.array.cumprod - Dataset.cumprod - DataArray.cumprod - :ref:`agg` - User guide on reduction or aggregation operations. - - Notes - ----- - Non-numeric variables will be removed prior to reducing. - - Examples - -------- - >>> from xarray import Variable - >>> variable = Variable( - ... "x", - ... np.array([1, 2, 3, 0, 2, np.nan]), - ... ) - >>> variable - - array([ 1., 2., 3., 0., 2., nan]) - - >>> variable.cumprod() - - array([1., 2., 6., 0., 0., 0.]) - - Use ``skipna`` to control whether NaNs are ignored. - - >>> variable.cumprod(skipna=False) - - array([ 1., 2., 6., 0., 0., nan]) - """ - return self.reduce( - duck_array_ops.cumprod, - dim=dim, - skipna=skipna, - keep_attrs=keep_attrs, - **kwargs, - ) diff --git a/xarray/core/variable.py b/xarray/core/variable.py index 230a35f7b57..a108a155be5 100644 --- a/xarray/core/variable.py +++ b/xarray/core/variable.py @@ -16,7 +16,6 @@ import xarray as xr # only for Dataset and DataArray from xarray.core import common, dtypes, duck_array_ops, indexing, nputils, ops, utils -from xarray.core._aggregations import VariableAggregations from xarray.core.arithmetic import VariableArithmetic from xarray.core.common import AbstractArray from xarray.core.indexing import ( @@ -312,7 +311,7 @@ def _as_array_or_item(data): return data -class Variable(VariableAggregations, NamedArray, AbstractArray, VariableArithmetic): +class Variable(NamedArray, AbstractArray, VariableArithmetic): """A netcdf-like variable consisting of dimensions, data and attributes which describe a single Array. A single Variable object is not fully described outside the context of its parent Dataset (if you want such a @@ -1751,25 +1750,17 @@ def reduce( _get_keep_attrs(default=False) if keep_attrs is None else keep_attrs ) - # If we were to simply subclass NamedArray alone then - # the call order for Variable.mean is + # Noe that the call order for Variable.mean is # Variable.mean -> NamedArray.mean -> Variable.reduce # -> NamedArray.reduce - # This means that the default keep_attrs will always be set - # to True by NamedArray.mean. - # Instead we need to make VariableAggregations mixin with .mean, - # and delegate to NamedArray.reduce setting keep_attrs explicitly - result = self._to_named_array().reduce( - func=func, - dim=dim, - axis=axis, - keep_attrs=keep_attrs_, - keepdims=keepdims, - **kwargs, + result = super().reduce( + func=func, dim=dim, axis=axis, keepdims=keepdims, **kwargs ) # return Variable always to support IndexVariable - return Variable(result.dims, result._data, attrs=result._attrs) + return Variable( + result.dims, result._data, attrs=result._attrs if keep_attrs_ else None + ) @classmethod def concat( diff --git a/xarray/namedarray/_aggregations.py b/xarray/namedarray/_aggregations.py index ba2673ca793..76dfb18d068 100644 --- a/xarray/namedarray/_aggregations.py +++ b/xarray/namedarray/_aggregations.py @@ -19,7 +19,6 @@ def reduce( dim: Dims = None, *, axis: int | Sequence[int] | None = None, - keep_attrs: bool = True, keepdims: bool = False, **kwargs: Any, ) -> Self: @@ -28,8 +27,6 @@ def reduce( def count( self, dim: Dims = None, - *, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -40,10 +37,6 @@ def count( 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 "..." or None, will reduce over all dimensions. - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``count`` on this object's data. @@ -82,15 +75,12 @@ def count( return self.reduce( duck_array_ops.count, dim=dim, - keep_attrs=keep_attrs, **kwargs, ) def all( self, dim: Dims = None, - *, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -101,10 +91,6 @@ def all( 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 "..." or None, will reduce over all dimensions. - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``all`` on this object's data. @@ -143,15 +129,12 @@ def all( return self.reduce( duck_array_ops.array_all, dim=dim, - keep_attrs=keep_attrs, **kwargs, ) def any( self, dim: Dims = None, - *, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -162,10 +145,6 @@ def any( 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 "..." or None, will reduce over all dimensions. - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``any`` on this object's data. @@ -204,7 +183,6 @@ def any( return self.reduce( duck_array_ops.array_any, dim=dim, - keep_attrs=keep_attrs, **kwargs, ) @@ -213,7 +191,6 @@ def max( dim: Dims = None, *, skipna: bool | None = None, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -229,10 +206,6 @@ def max( skips missing values for float dtypes; other dtypes either do not have a sentinel missing value (int) or ``skipna=True`` has not been implemented (object, datetime64 or timedelta64). - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``max`` on this object's data. @@ -278,7 +251,6 @@ def max( duck_array_ops.max, dim=dim, skipna=skipna, - keep_attrs=keep_attrs, **kwargs, ) @@ -287,7 +259,6 @@ def min( dim: Dims = None, *, skipna: bool | None = None, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -303,10 +274,6 @@ def min( skips missing values for float dtypes; other dtypes either do not have a sentinel missing value (int) or ``skipna=True`` has not been implemented (object, datetime64 or timedelta64). - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``min`` on this object's data. @@ -352,7 +319,6 @@ def min( duck_array_ops.min, dim=dim, skipna=skipna, - keep_attrs=keep_attrs, **kwargs, ) @@ -361,7 +327,6 @@ def mean( dim: Dims = None, *, skipna: bool | None = None, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -377,10 +342,6 @@ def mean( skips missing values for float dtypes; other dtypes either do not have a sentinel missing value (int) or ``skipna=True`` has not been implemented (object, datetime64 or timedelta64). - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``mean`` on this object's data. @@ -430,7 +391,6 @@ def mean( duck_array_ops.mean, dim=dim, skipna=skipna, - keep_attrs=keep_attrs, **kwargs, ) @@ -440,7 +400,6 @@ def prod( *, skipna: bool | None = None, min_count: int | None = None, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -462,10 +421,6 @@ def prod( NA. Only used if skipna is set to True or defaults to True for the array's dtype. Changed in version 0.17.0: if specified on an integer array and skipna=True, the result will be a float array. - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``prod`` on this object's data. @@ -522,7 +477,6 @@ def prod( dim=dim, skipna=skipna, min_count=min_count, - keep_attrs=keep_attrs, **kwargs, ) @@ -532,7 +486,6 @@ def sum( *, skipna: bool | None = None, min_count: int | None = None, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -554,10 +507,6 @@ def sum( NA. Only used if skipna is set to True or defaults to True for the array's dtype. Changed in version 0.17.0: if specified on an integer array and skipna=True, the result will be a float array. - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``sum`` on this object's data. @@ -614,7 +563,6 @@ def sum( dim=dim, skipna=skipna, min_count=min_count, - keep_attrs=keep_attrs, **kwargs, ) @@ -624,7 +572,6 @@ def std( *, skipna: bool | None = None, ddof: int = 0, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -643,10 +590,6 @@ def std( ddof : int, default: 0 “Delta Degrees of Freedom”: the divisor used in the calculation is ``N - ddof``, where ``N`` represents the number of elements. - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``std`` on this object's data. @@ -703,7 +646,6 @@ def std( dim=dim, skipna=skipna, ddof=ddof, - keep_attrs=keep_attrs, **kwargs, ) @@ -713,7 +655,6 @@ def var( *, skipna: bool | None = None, ddof: int = 0, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -732,10 +673,6 @@ def var( ddof : int, default: 0 “Delta Degrees of Freedom”: the divisor used in the calculation is ``N - ddof``, where ``N`` represents the number of elements. - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``var`` on this object's data. @@ -792,7 +729,6 @@ def var( dim=dim, skipna=skipna, ddof=ddof, - keep_attrs=keep_attrs, **kwargs, ) @@ -801,7 +737,6 @@ def median( dim: Dims = None, *, skipna: bool | None = None, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -817,10 +752,6 @@ def median( skips missing values for float dtypes; other dtypes either do not have a sentinel missing value (int) or ``skipna=True`` has not been implemented (object, datetime64 or timedelta64). - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``median`` on this object's data. @@ -870,7 +801,6 @@ def median( duck_array_ops.median, dim=dim, skipna=skipna, - keep_attrs=keep_attrs, **kwargs, ) @@ -879,7 +809,6 @@ def cumsum( dim: Dims = None, *, skipna: bool | None = None, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -895,10 +824,6 @@ def cumsum( skips missing values for float dtypes; other dtypes either do not have a sentinel missing value (int) or ``skipna=True`` has not been implemented (object, datetime64 or timedelta64). - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``cumsum`` on this object's data. @@ -948,7 +873,6 @@ def cumsum( duck_array_ops.cumsum, dim=dim, skipna=skipna, - keep_attrs=keep_attrs, **kwargs, ) @@ -957,7 +881,6 @@ def cumprod( dim: Dims = None, *, skipna: bool | None = None, - keep_attrs: bool = True, **kwargs: Any, ) -> Self: """ @@ -973,10 +896,6 @@ def cumprod( skips missing values for float dtypes; other dtypes either do not have a sentinel missing value (int) or ``skipna=True`` has not been implemented (object, datetime64 or timedelta64). - keep_attrs : bool, optional - If True, ``attrs`` will be copied from the original - object to the new one. If False, the new object will be - returned without attributes. **kwargs : Any Additional keyword arguments passed on to the appropriate array function for calculating ``cumprod`` on this object's data. @@ -1026,6 +945,5 @@ def cumprod( duck_array_ops.cumprod, dim=dim, skipna=skipna, - keep_attrs=keep_attrs, **kwargs, ) diff --git a/xarray/namedarray/core.py b/xarray/namedarray/core.py index ba467e0beef..a90cc6c02a4 100644 --- a/xarray/namedarray/core.py +++ b/xarray/namedarray/core.py @@ -498,7 +498,6 @@ def reduce( func: Callable[..., Any], dim: Dims = None, axis: int | Sequence[int] | None = None, - keep_attrs: bool = True, keepdims: bool = False, **kwargs, ) -> Self: @@ -518,10 +517,6 @@ def reduce( and 'axis' arguments can be supplied. If neither are supplied, then the reduction is calculated over the flattened array (by calling `func(x)` without an axis argument). - keep_attrs : bool, optional - If True, the variable's attributes (`attrs`) will be copied from - the original object to the new one. If False (default), the new - object will be returned without attributes. keepdims : bool, default: False If True, the dimensions which are reduced are left in the result as dimensions of size one @@ -580,12 +575,8 @@ def reduce( adim for n, adim in enumerate(self.dims) if n not in removed_axes ) - attrs = self._attrs if keep_attrs else None - - # We need to return NamedArray rather than the type of `self` at the moment, ref - # #8216 - # To handle IndexVariable - return NamedArray(dims, data, attrs=attrs) + # Return NamedArray to handle IndexVariable when data is nD + return NamedArray(dims, data, attrs=self._attrs) def _nonzero(self) -> tuple[Self, ...]: """Equivalent numpy's nonzero but returns a tuple of NamedArrays.""" diff --git a/xarray/util/generate_aggregations.py b/xarray/util/generate_aggregations.py index 94da5e2316d..39fb59d0fac 100644 --- a/xarray/util/generate_aggregations.py +++ b/xarray/util/generate_aggregations.py @@ -61,7 +61,23 @@ def reduce( dim: Dims = None, *, axis: int | Sequence[int] | None = None, - keep_attrs{keep_attrs_type}, + keep_attrs: bool | None = None, + keepdims: bool = False, + **kwargs: Any, + ) -> Self: + raise NotImplementedError()""" + +NAMED_ARRAY_AGGREGATIONS_PREAMBLE = """ + +class {obj}{cls}Aggregations: + __slots__ = () + + def reduce( + self, + func: Callable[..., Any], + dim: Dims = None, + *, + axis: int | Sequence[int] | None = None, keepdims: bool = False, **kwargs: Any, ) -> Self: @@ -119,9 +135,7 @@ def _flox_reduce( TEMPLATE_REDUCTION_SIGNATURE = ''' def {method}( self, - dim: Dims = None, - *,{extra_kwargs} - keep_attrs{keep_attrs_type}, + dim: Dims = None,{kw_only}{extra_kwargs}{keep_attrs} **kwargs: Any, ) -> Self: """ @@ -189,7 +203,7 @@ def {method}( “Delta Degrees of Freedom”: the divisor used in the calculation is ``N - ddof``, where ``N`` represents the number of elements.""" -_KEEP_ATTRS_DOCSTRING = """keep_attrs : {keep_attrs_type}, optional +_KEEP_ATTRS_DOCSTRING = """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 returned without attributes.""" @@ -241,8 +255,6 @@ def {method}( >>> {calculation}(skipna=True, ddof=1)""", ) -from dataclasses import field - @dataclass class DataStructure: @@ -250,7 +262,6 @@ class DataStructure: create_example: str example_var_name: str numeric_only: bool = False - keep_attrs_type: str = field(default=": bool | None = None") see_also_modules: tuple[str] = tuple @@ -291,6 +302,7 @@ def __init__( docref_description, example_call_preamble, definition_preamble, + has_keep_attrs=True, notes=None, ): self.datastructure = datastructure @@ -299,11 +311,8 @@ def __init__( self.docref = docref self.docref_description = docref_description self.example_call_preamble = example_call_preamble - self.preamble = definition_preamble.format( - obj=datastructure.name, - cls=cls, - keep_attrs_type=datastructure.keep_attrs_type, - ) + self.has_keep_attrs = has_keep_attrs + self.preamble = definition_preamble.format(obj=datastructure.name, cls=cls) self.notes = "" if notes is None else notes def generate_methods(self): @@ -312,10 +321,15 @@ def generate_methods(self): yield self.generate_method(method) def generate_method(self, method): + has_kw_only = method.extra_kwargs or self.has_keep_attrs + template_kwargs = dict( obj=self.datastructure.name, method=method.name, - keep_attrs_type=self.datastructure.keep_attrs_type, + keep_attrs="\n keep_attrs: bool | None = None," + if self.has_keep_attrs + else "", + kw_only="\n *," if has_kw_only else "", ) if method.extra_kwargs: @@ -333,11 +347,7 @@ def generate_method(self, method): for text in [ self._dim_docstring.format(method=method.name, cls=self.cls), *(kwarg.docs for kwarg in method.extra_kwargs if kwarg.docs), - _KEEP_ATTRS_DOCSTRING.format( - keep_attrs_type="bool or None" - if "None" in self.datastructure.keep_attrs_type - else "bool" - ), + _KEEP_ATTRS_DOCSTRING if self.has_keep_attrs else None, _KWARGS_DOCSTRING.format(method=method.name), ]: if text: @@ -377,7 +387,7 @@ def generate_method(self, method): yield textwrap.indent(self.generate_example(method=method), "") yield ' """' - yield self.generate_code(method) + yield self.generate_code(method, self.has_keep_attrs) def generate_example(self, method): created = self.datastructure.create_example.format( @@ -403,7 +413,7 @@ class GroupByAggregationGenerator(AggregationGenerator): _dim_docstring = _DIM_DOCSTRING_GROUPBY _template_signature = TEMPLATE_REDUCTION_SIGNATURE_GROUPBY - def generate_code(self, method): + def generate_code(self, method, has_keep_attrs): extra_kwargs = [kwarg.call for kwarg in method.extra_kwargs if kwarg.call] if self.datastructure.numeric_only: @@ -455,7 +465,7 @@ def generate_code(self, method): class GenericAggregationGenerator(AggregationGenerator): - def generate_code(self, method): + def generate_code(self, method, has_keep_attrs): extra_kwargs = [kwarg.call for kwarg in method.extra_kwargs if kwarg.call] if self.datastructure.numeric_only: @@ -465,11 +475,13 @@ def generate_code(self, method): extra_kwargs = textwrap.indent("\n" + "\n".join(extra_kwargs), 12 * " ") else: extra_kwargs = "" + keep_attrs = ( + "\n" + 12 * " " + "keep_attrs=keep_attrs," if has_keep_attrs else "" + ) return f"""\ return self.reduce( duck_array_ops.{method.array_method}, - dim=dim,{extra_kwargs} - keep_attrs=keep_attrs, + dim=dim,{extra_kwargs}{keep_attrs} **kwargs, )""" @@ -581,28 +593,6 @@ def generate_code(self, method): notes=_FLOX_RESAMPLE_NOTES, ) -VARIABLE_OBJECT = DataStructure( - name="Variable", - create_example=""" - >>> from xarray import Variable - >>> variable = Variable( - ... "x",{example_array}, - ... )""", - example_var_name="variable", - numeric_only=False, # TODO - see_also_modules=("Dataset", "DataArray"), -) - -VARIABLE_GENERATOR = GenericAggregationGenerator( - cls="", - datastructure=VARIABLE_OBJECT, - methods=AGGREGATION_METHODS, - docref="agg", - docref_description="reduction or aggregation operations", - example_call_preamble="", - definition_preamble=AGGREGATIONS_PREAMBLE, -) - NAMED_ARRAY_OBJECT = DataStructure( name="NamedArray", create_example=""" @@ -612,7 +602,6 @@ def generate_code(self, method): ... )""", example_var_name="na", numeric_only=False, # TODO - keep_attrs_type=": bool = True", see_also_modules=("Dataset", "DataArray"), ) @@ -623,7 +612,8 @@ def generate_code(self, method): docref="agg", docref_description="reduction or aggregation operations", example_call_preamble="", - definition_preamble=AGGREGATIONS_PREAMBLE, + definition_preamble=NAMED_ARRAY_AGGREGATIONS_PREAMBLE, + has_keep_attrs=False, ) @@ -650,7 +640,6 @@ def write_methods(filepath, generators, preamble): DATASET_RESAMPLE_GENERATOR, DATAARRAY_GROUPBY_GENERATOR, DATAARRAY_RESAMPLE_GENERATOR, - VARIABLE_GENERATOR, ], preamble=MODULE_PREAMBLE, )