From e227c0bd5648684af2a2a329024dfde5eff4e7fd Mon Sep 17 00:00:00 2001 From: Maximilian Roos <5635139+max-sixty@users.noreply.github.com> Date: Wed, 2 Oct 2024 18:15:52 -0700 Subject: [PATCH] Add `.cumulative` to `cumsum` & `cumprod` docstrings (#9533) * Remove doctests so we can work with it * Add generated docstrings * Add generated doctest outputs * Update docs for running generations * add named array generations * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * . * Update xarray/util/generate_aggregations.py Co-authored-by: Deepak Cherian --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com> Co-authored-by: Deepak Cherian --- xarray/core/_aggregations.py | 60 ++++++++++++++++++++++++++++ xarray/namedarray/_aggregations.py | 10 +++++ xarray/util/generate_aggregations.py | 51 ++++++++++++++++++----- 3 files changed, 111 insertions(+), 10 deletions(-) diff --git a/xarray/core/_aggregations.py b/xarray/core/_aggregations.py index 5342db31fd0..b557ad44a32 100644 --- a/xarray/core/_aggregations.py +++ b/xarray/core/_aggregations.py @@ -1069,6 +1069,7 @@ def cumsum( numpy.cumsum dask.array.cumsum DataArray.cumsum + Dataset.cumulative :ref:`agg` User guide on reduction or aggregation operations. @@ -1076,6 +1077,10 @@ def cumsum( ----- Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> da = xr.DataArray( @@ -1162,6 +1167,7 @@ def cumprod( numpy.cumprod dask.array.cumprod DataArray.cumprod + Dataset.cumulative :ref:`agg` User guide on reduction or aggregation operations. @@ -1169,6 +1175,10 @@ def cumprod( ----- Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> da = xr.DataArray( @@ -2175,6 +2185,7 @@ def cumsum( numpy.cumsum dask.array.cumsum Dataset.cumsum + DataArray.cumulative :ref:`agg` User guide on reduction or aggregation operations. @@ -2182,6 +2193,10 @@ def cumsum( ----- Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> da = xr.DataArray( @@ -2264,6 +2279,7 @@ def cumprod( numpy.cumprod dask.array.cumprod Dataset.cumprod + DataArray.cumulative :ref:`agg` User guide on reduction or aggregation operations. @@ -2271,6 +2287,10 @@ def cumprod( ----- Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> da = xr.DataArray( @@ -3644,6 +3664,7 @@ def cumsum( numpy.cumsum dask.array.cumsum Dataset.cumsum + Dataset.cumulative :ref:`groupby` User guide on groupby operations. @@ -3656,6 +3677,10 @@ def cumsum( Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> da = xr.DataArray( @@ -3743,6 +3768,7 @@ def cumprod( numpy.cumprod dask.array.cumprod Dataset.cumprod + Dataset.cumulative :ref:`groupby` User guide on groupby operations. @@ -3755,6 +3781,10 @@ def cumprod( Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> da = xr.DataArray( @@ -5132,6 +5162,7 @@ def cumsum( numpy.cumsum dask.array.cumsum Dataset.cumsum + Dataset.cumulative :ref:`resampling` User guide on resampling operations. @@ -5144,6 +5175,10 @@ def cumsum( Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> da = xr.DataArray( @@ -5231,6 +5266,7 @@ def cumprod( numpy.cumprod dask.array.cumprod Dataset.cumprod + Dataset.cumulative :ref:`resampling` User guide on resampling operations. @@ -5243,6 +5279,10 @@ def cumprod( Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> da = xr.DataArray( @@ -6520,6 +6560,7 @@ def cumsum( numpy.cumsum dask.array.cumsum DataArray.cumsum + DataArray.cumulative :ref:`groupby` User guide on groupby operations. @@ -6532,6 +6573,10 @@ def cumsum( Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> da = xr.DataArray( @@ -6615,6 +6660,7 @@ def cumprod( numpy.cumprod dask.array.cumprod DataArray.cumprod + DataArray.cumulative :ref:`groupby` User guide on groupby operations. @@ -6627,6 +6673,10 @@ def cumprod( Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> da = xr.DataArray( @@ -7900,6 +7950,7 @@ def cumsum( numpy.cumsum dask.array.cumsum DataArray.cumsum + DataArray.cumulative :ref:`resampling` User guide on resampling operations. @@ -7912,6 +7963,10 @@ def cumsum( Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> da = xr.DataArray( @@ -7995,6 +8050,7 @@ def cumprod( numpy.cumprod dask.array.cumprod DataArray.cumprod + DataArray.cumulative :ref:`resampling` User guide on resampling operations. @@ -8007,6 +8063,10 @@ def cumprod( Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> da = xr.DataArray( diff --git a/xarray/namedarray/_aggregations.py b/xarray/namedarray/_aggregations.py index 4889b7bd106..48001422386 100644 --- a/xarray/namedarray/_aggregations.py +++ b/xarray/namedarray/_aggregations.py @@ -842,6 +842,7 @@ def cumsum( dask.array.cumsum Dataset.cumsum DataArray.cumsum + NamedArray.cumulative :ref:`agg` User guide on reduction or aggregation operations. @@ -849,6 +850,10 @@ def cumsum( ----- Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> from xarray.namedarray.core import NamedArray @@ -914,6 +919,7 @@ def cumprod( dask.array.cumprod Dataset.cumprod DataArray.cumprod + NamedArray.cumulative :ref:`agg` User guide on reduction or aggregation operations. @@ -921,6 +927,10 @@ def cumprod( ----- Non-numeric variables will be removed prior to reducing. + Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) + and better supported. ``cumsum`` and ``cumprod`` may be deprecated + in the future. + Examples -------- >>> from xarray.namedarray.core import NamedArray diff --git a/xarray/util/generate_aggregations.py b/xarray/util/generate_aggregations.py index d93c94b1a76..d2fc4f6d4e2 100644 --- a/xarray/util/generate_aggregations.py +++ b/xarray/util/generate_aggregations.py @@ -4,8 +4,8 @@ Usage: python xarray/util/generate_aggregations.py - pytest --doctest-modules xarray/core/_aggregations.py --accept || true - pytest --doctest-modules xarray/core/_aggregations.py + pytest --doctest-modules xarray/{core,namedarray}/_aggregations.py --accept || true + pytest --doctest-modules xarray/{core,namedarray}/_aggregations.py This requires [pytest-accept](https://github.com/max-sixty/pytest-accept). The second run of pytest is deliberate, since the first will return an error @@ -24,8 +24,8 @@ from __future__ import annotations -from collections.abc import Sequence -from typing import TYPE_CHECKING, Any, Callable +from collections.abc import Callable, Sequence +from typing import TYPE_CHECKING, Any from xarray.core import duck_array_ops from xarray.core.options import OPTIONS @@ -45,8 +45,8 @@ from __future__ import annotations -from collections.abc import Sequence -from typing import Any, Callable +from collections.abc import Callable, Sequence +from typing import Any from xarray.core import duck_array_ops from xarray.core.types import Dims, Self @@ -223,6 +223,9 @@ def {method}( See the `flox documentation `_ for more.""" _FLOX_GROUPBY_NOTES = _FLOX_NOTES_TEMPLATE.format(kind="groupby") _FLOX_RESAMPLE_NOTES = _FLOX_NOTES_TEMPLATE.format(kind="resampling") +_CUM_NOTES = """Note that the methods on the ``cumulative`` method are more performant (with numbagg installed) +and better supported. ``cumsum`` and ``cumprod`` may be deprecated +in the future.""" ExtraKwarg = collections.namedtuple("ExtraKwarg", "docs kwarg call example") skipna = ExtraKwarg( @@ -271,13 +274,17 @@ def __init__( extra_kwargs=tuple(), numeric_only=False, see_also_modules=("numpy", "dask.array"), + see_also_methods=(), min_flox_version=None, + additional_notes="", ): self.name = name self.extra_kwargs = extra_kwargs self.numeric_only = numeric_only self.see_also_modules = see_also_modules + self.see_also_methods = see_also_methods self.min_flox_version = min_flox_version + self.additional_notes = additional_notes if bool_reduce: self.array_method = f"array_{name}" self.np_example_array = """ @@ -315,7 +322,7 @@ def generate_methods(self): for method in self.methods: yield self.generate_method(method) - def generate_method(self, method): + def generate_method(self, method: Method): has_kw_only = method.extra_kwargs or self.has_keep_attrs template_kwargs = dict( @@ -360,10 +367,17 @@ def generate_method(self, method): if self.cls == "" else (self.datastructure.name,) ) - see_also_methods = "\n".join( + see_also_methods_from_modules = ( " " * 8 + f"{mod}.{method.name}" for mod in (method.see_also_modules + others) ) + see_also_methods_from_methods = ( + " " * 8 + f"{self.datastructure.name}.{method}" + for method in method.see_also_methods + ) + see_also_methods = "\n".join( + [*see_also_methods_from_modules, *see_also_methods_from_methods] + ) # Fixes broken links mentioned in #8055 yield TEMPLATE_SEE_ALSO.format( **template_kwargs, @@ -378,6 +392,11 @@ def generate_method(self, method): notes += "\n\n" notes += _NUMERIC_ONLY_NOTES + if method.additional_notes: + if notes != "": + notes += "\n\n" + notes += method.additional_notes + if notes != "": yield TEMPLATE_NOTES.format(notes=textwrap.indent(notes, 8 * " ")) @@ -505,8 +524,20 @@ def generate_code(self, method, has_keep_attrs): "median", extra_kwargs=(skipna,), numeric_only=True, min_flox_version="0.9.2" ), # Cumulatives: - Method("cumsum", extra_kwargs=(skipna,), numeric_only=True), - Method("cumprod", extra_kwargs=(skipna,), numeric_only=True), + Method( + "cumsum", + extra_kwargs=(skipna,), + numeric_only=True, + see_also_methods=("cumulative",), + additional_notes=_CUM_NOTES, + ), + Method( + "cumprod", + extra_kwargs=(skipna,), + numeric_only=True, + see_also_methods=("cumulative",), + additional_notes=_CUM_NOTES, + ), )