diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 0b611e88453..6b944fd1b30 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -39,7 +39,10 @@ Bug fixes - Fix silently overwriting the `engine` key when passing :py:func:`open_dataset` a file object to an incompatible netCDF (:issue:`4457`). Now incompatible combinations of files and engines raise an exception instead. By `Alessandro Amici `_. - +- The ``min_count`` argument to :py:meth:`DataArray.sum()` and :py:meth:`DataArray.prod()` + is now ignored when not applicable, i.e. when ``skipna=False`` or when ``skipna=None`` + and the dtype does not have a missing value (:issue:`4352`). + By `Mathias Hauser `_. Documentation ~~~~~~~~~~~~~ diff --git a/xarray/core/duck_array_ops.py b/xarray/core/duck_array_ops.py index 53849a3eac8..f35dfd236be 100644 --- a/xarray/core/duck_array_ops.py +++ b/xarray/core/duck_array_ops.py @@ -325,6 +325,8 @@ def f(values, axis=None, skipna=None, **kwargs): nanname = "nan" + name func = getattr(nanops, nanname) else: + if name in ["sum", "prod"]: + kwargs.pop("min_count", None) func = _dask_or_eager_func(name, dask_module=dask_module) try: @@ -361,7 +363,7 @@ def f(values, axis=None, skipna=None, **kwargs): median.numeric_only = True prod = _create_nan_agg_method("prod") prod.numeric_only = True -sum.available_min_count = True +prod.available_min_count = True cumprod_1d = _create_nan_agg_method("cumprod") cumprod_1d.numeric_only = True cumsum_1d = _create_nan_agg_method("cumsum") diff --git a/xarray/tests/test_duck_array_ops.py b/xarray/tests/test_duck_array_ops.py index 41f03115bc3..44b2ed23357 100644 --- a/xarray/tests/test_duck_array_ops.py +++ b/xarray/tests/test_duck_array_ops.py @@ -580,15 +580,17 @@ def test_dask_gradient(axis, edge_order): @pytest.mark.parametrize("dask", [False, True]) @pytest.mark.parametrize("func", ["sum", "prod"]) @pytest.mark.parametrize("aggdim", [None, "x"]) -def test_min_count(dim_num, dtype, dask, func, aggdim): +@pytest.mark.parametrize("contains_nan", [True, False]) +@pytest.mark.parametrize("skipna", [True, False, None]) +def test_min_count(dim_num, dtype, dask, func, aggdim, contains_nan, skipna): if dask and not has_dask: pytest.skip("requires dask") - da = construct_dataarray(dim_num, dtype, contains_nan=True, dask=dask) + da = construct_dataarray(dim_num, dtype, contains_nan=contains_nan, dask=dask) min_count = 3 - actual = getattr(da, func)(dim=aggdim, skipna=True, min_count=min_count) - expected = series_reduce(da, func, skipna=True, dim=aggdim, min_count=min_count) + actual = getattr(da, func)(dim=aggdim, skipna=skipna, min_count=min_count) + expected = series_reduce(da, func, skipna=skipna, dim=aggdim, min_count=min_count) assert_allclose(actual, expected) assert_dask_array(actual, dask)