From 1e1d31b5f13e0f078296e429388bd4ae504d3e1f Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Fri, 7 Apr 2023 17:32:23 +0200 Subject: [PATCH 1/3] WARN: std and var showing RuntimeWarning for ea dtype with one element --- doc/source/whatsnew/v2.0.1.rst | 2 +- pandas/core/array_algos/masked_reductions.py | 4 ++-- pandas/tests/series/methods/test_describe.py | 12 ++++++++++++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v2.0.1.rst b/doc/source/whatsnew/v2.0.1.rst index bf21d6402d621..bdc87878dd185 100644 --- a/doc/source/whatsnew/v2.0.1.rst +++ b/doc/source/whatsnew/v2.0.1.rst @@ -13,7 +13,7 @@ including other versions of pandas. Fixed regressions ~~~~~~~~~~~~~~~~~ -- +- Fixed regression in :meth:`Series.describe` showing ``RuntimeWarning`` for extension dtype :class:`Series` with one element (:issue:`52515`) .. --------------------------------------------------------------------------- .. _whatsnew_201.bug_fixes: diff --git a/pandas/core/array_algos/masked_reductions.py b/pandas/core/array_algos/masked_reductions.py index 7900bcc6a8e6e..8c79791b17d9c 100644 --- a/pandas/core/array_algos/masked_reductions.py +++ b/pandas/core/array_algos/masked_reductions.py @@ -168,7 +168,7 @@ def var( axis: AxisInt | None = None, ddof: int = 1, ): - if not values.size or mask.all(): + if not values.size or mask.all() or len(values) == 1: return libmissing.NA return _reductions( @@ -184,7 +184,7 @@ def std( axis: AxisInt | None = None, ddof: int = 1, ): - if not values.size or mask.all(): + if not values.size or mask.all() or len(values) == 1: return libmissing.NA return _reductions( diff --git a/pandas/tests/series/methods/test_describe.py b/pandas/tests/series/methods/test_describe.py index ab4b8881d677d..6876a0c848412 100644 --- a/pandas/tests/series/methods/test_describe.py +++ b/pandas/tests/series/methods/test_describe.py @@ -9,6 +9,7 @@ ) from pandas import ( + NA, Period, Series, Timedelta, @@ -187,3 +188,14 @@ def test_numeric_result_dtype(self, any_numeric_dtype): dtype=dtype, ) tm.assert_series_equal(result, expected) + + def test_describe_one_element_ea(self): + # GH#52515 + ser = Series([0.0], dtype="Float64") + result = ser.describe() + expected = Series( + [1, 0, NA, 0, 0, 0, 0, 0], + dtype="Float64", + index=["count", "mean", "std", "min", "25%", "50%", "75%", "max"], + ) + tm.assert_series_equal(result, expected) From 5b9c5b30d31616b8700ed35cdbac72efb113e93b Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Fri, 7 Apr 2023 19:33:40 +0200 Subject: [PATCH 2/3] Filter warnings --- pandas/core/array_algos/masked_reductions.py | 21 ++++++++++++-------- pandas/tests/series/methods/test_describe.py | 3 ++- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/pandas/core/array_algos/masked_reductions.py b/pandas/core/array_algos/masked_reductions.py index 8c79791b17d9c..60a8d349984b9 100644 --- a/pandas/core/array_algos/masked_reductions.py +++ b/pandas/core/array_algos/masked_reductions.py @@ -8,6 +8,7 @@ TYPE_CHECKING, Callable, ) +import warnings import numpy as np @@ -168,12 +169,14 @@ def var( axis: AxisInt | None = None, ddof: int = 1, ): - if not values.size or mask.all() or len(values) == 1: + if not values.size or mask.all(): return libmissing.NA - return _reductions( - np.var, values=values, mask=mask, skipna=skipna, axis=axis, ddof=ddof - ) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", RuntimeWarning) + return _reductions( + np.var, values=values, mask=mask, skipna=skipna, axis=axis, ddof=ddof + ) def std( @@ -184,9 +187,11 @@ def std( axis: AxisInt | None = None, ddof: int = 1, ): - if not values.size or mask.all() or len(values) == 1: + if not values.size or mask.all(): return libmissing.NA - return _reductions( - np.std, values=values, mask=mask, skipna=skipna, axis=axis, ddof=ddof - ) + with warnings.catch_warnings(): + warnings.simplefilter("ignore", RuntimeWarning) + return _reductions( + np.std, values=values, mask=mask, skipna=skipna, axis=axis, ddof=ddof + ) diff --git a/pandas/tests/series/methods/test_describe.py b/pandas/tests/series/methods/test_describe.py index 6876a0c848412..0062d45cc68a0 100644 --- a/pandas/tests/series/methods/test_describe.py +++ b/pandas/tests/series/methods/test_describe.py @@ -192,7 +192,8 @@ def test_numeric_result_dtype(self, any_numeric_dtype): def test_describe_one_element_ea(self): # GH#52515 ser = Series([0.0], dtype="Float64") - result = ser.describe() + with tm.assert_produces_warning(None): + result = ser.describe() expected = Series( [1, 0, NA, 0, 0, 0, 0, 0], dtype="Float64", From 21694f5f41063cf4e080fbc3e3d417a38fec91d0 Mon Sep 17 00:00:00 2001 From: Patrick Hoefler Date: Sat, 8 Apr 2023 00:02:08 +0200 Subject: [PATCH 3/3] Fix test --- pandas/tests/extension/base/dim2.py | 8 +------- pandas/tests/frame/methods/test_describe.py | 4 +--- 2 files changed, 2 insertions(+), 10 deletions(-) diff --git a/pandas/tests/extension/base/dim2.py b/pandas/tests/extension/base/dim2.py index 6371411f9992c..6e717afaeeb2d 100644 --- a/pandas/tests/extension/base/dim2.py +++ b/pandas/tests/extension/base/dim2.py @@ -12,7 +12,6 @@ ) import pandas as pd -import pandas._testing as tm from pandas.core.arrays.integer import INT_STR_TO_DTYPE from pandas.tests.extension.base.base import BaseExtensionTests @@ -200,12 +199,7 @@ def test_reductions_2d_axis0(self, data, method): kwargs["ddof"] = 0 try: - if method in ["mean", "var", "std"] and hasattr(data, "_mask"): - # Empty slices produced by the mask cause RuntimeWarnings by numpy - with tm.assert_produces_warning(RuntimeWarning, check_stacklevel=False): - result = getattr(arr2d, method)(axis=0, **kwargs) - else: - result = getattr(arr2d, method)(axis=0, **kwargs) + result = getattr(arr2d, method)(axis=0, **kwargs) except Exception as err: try: getattr(data, method)() diff --git a/pandas/tests/frame/methods/test_describe.py b/pandas/tests/frame/methods/test_describe.py index ecd784ca5658e..e2b8a0f63c31a 100644 --- a/pandas/tests/frame/methods/test_describe.py +++ b/pandas/tests/frame/methods/test_describe.py @@ -388,9 +388,7 @@ def test_ea_with_na(self, any_numeric_ea_dtype): # GH#48778 df = DataFrame({"a": [1, pd.NA, pd.NA], "b": pd.NA}, dtype=any_numeric_ea_dtype) - # Warning from numpy for taking std of single element - with tm.assert_produces_warning(RuntimeWarning, check_stacklevel=False): - result = df.describe() + result = df.describe() expected = DataFrame( {"a": [1.0, 1.0, pd.NA] + [1.0] * 5, "b": [0.0] + [pd.NA] * 7}, index=["count", "mean", "std", "min", "25%", "50%", "75%", "max"],