From 4c6311cf8fdad8b46dac3a36216a3f54d11cf302 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Thu, 24 Jan 2019 09:47:16 -0600 Subject: [PATCH 1/2] Disable M8 in nanops Closes https://github.com/pandas-dev/pandas/issues/24752 --- pandas/core/nanops.py | 1 + pandas/tests/frame/test_analytics.py | 16 ++++++++++++++++ pandas/tests/test_nanops.py | 3 +++ 3 files changed, 20 insertions(+) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index cafd3a9915fa0..7677863108073 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -437,6 +437,7 @@ def nansum(values, axis=None, skipna=True, min_count=0, mask=None): return _wrap_results(the_sum, dtype) +@disallow('M8') @bottleneck_switch() def nanmean(values, axis=None, skipna=True, mask=None): """ diff --git a/pandas/tests/frame/test_analytics.py b/pandas/tests/frame/test_analytics.py index f2c3f50c291c3..7110fc2fdb71a 100644 --- a/pandas/tests/frame/test_analytics.py +++ b/pandas/tests/frame/test_analytics.py @@ -794,6 +794,22 @@ def test_mean(self, float_frame_with_na, float_frame, float_string_frame): check_dates=True) assert_stat_op_api('mean', float_frame, float_string_frame) + def test_mean_mixed_datetime_numeric(self): + # https://github.com/pandas-dev/pandas/issues/24752 + df = pd.DataFrame({"A": [1, 1], "B": [pd.Timestamp('2000')] * 2}) + result = df.mean() + expected = pd.Series([1.0], index=['A']) + tm.assert_series_equal(result, expected) + + def test_mean_excludeds_datetimes(self): + # https://github.com/pandas-dev/pandas/issues/24752 + # Our long-term desired behavior is unclear, but the behavior in + # 0.24.0rc1 was buggy. + df = pd.DataFrame({"A": [pd.Timestamp('2000')] * 2}) + result = df.mean() + expected = pd.Series() + tm.assert_series_equal(result, expected) + def test_product(self, float_frame_with_na, float_frame, float_string_frame): assert_stat_op_calc('product', np.prod, float_frame_with_na) diff --git a/pandas/tests/test_nanops.py b/pandas/tests/test_nanops.py index 4bcd16a86e865..cf5ef6cf15eca 100644 --- a/pandas/tests/test_nanops.py +++ b/pandas/tests/test_nanops.py @@ -971,6 +971,9 @@ def prng(self): class TestDatetime64NaNOps(object): @pytest.mark.parametrize('tz', [None, 'UTC']) + @pytest.mark.xfail(reason="disabled") + # Enabling mean changes the behavior of DataFrame.mean + # See https://github.com/pandas-dev/pandas/issues/24752 def test_nanmean(self, tz): dti = pd.date_range('2016-01-01', periods=3, tz=tz) expected = dti[1] From 61964790b8f5808643f72e5ea5fed1874a3993e6 Mon Sep 17 00:00:00 2001 From: Tom Augspurger Date: Thu, 24 Jan 2019 10:21:27 -0600 Subject: [PATCH 2/2] disallow datetimetz --- pandas/core/nanops.py | 7 ++++--- pandas/tests/frame/test_analytics.py | 11 +++++++---- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 7677863108073..86c3c380636c9 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -14,7 +14,8 @@ _get_dtype, is_any_int_dtype, is_bool_dtype, is_complex, is_complex_dtype, is_datetime64_dtype, is_datetime64tz_dtype, is_datetime_or_timedelta_dtype, is_float, is_float_dtype, is_integer, is_integer_dtype, is_numeric_dtype, - is_object_dtype, is_scalar, is_timedelta64_dtype) + is_object_dtype, is_scalar, is_timedelta64_dtype, pandas_dtype) +from pandas.core.dtypes.dtypes import DatetimeTZDtype from pandas.core.dtypes.missing import isna, na_value_for_dtype, notna import pandas.core.common as com @@ -57,7 +58,7 @@ class disallow(object): def __init__(self, *dtypes): super(disallow, self).__init__() - self.dtypes = tuple(np.dtype(dtype).type for dtype in dtypes) + self.dtypes = tuple(pandas_dtype(dtype).type for dtype in dtypes) def check(self, obj): return hasattr(obj, 'dtype') and issubclass(obj.dtype.type, @@ -437,7 +438,7 @@ def nansum(values, axis=None, skipna=True, min_count=0, mask=None): return _wrap_results(the_sum, dtype) -@disallow('M8') +@disallow('M8', DatetimeTZDtype) @bottleneck_switch() def nanmean(values, axis=None, skipna=True, mask=None): """ diff --git a/pandas/tests/frame/test_analytics.py b/pandas/tests/frame/test_analytics.py index 7110fc2fdb71a..386e5f57617cf 100644 --- a/pandas/tests/frame/test_analytics.py +++ b/pandas/tests/frame/test_analytics.py @@ -794,18 +794,21 @@ def test_mean(self, float_frame_with_na, float_frame, float_string_frame): check_dates=True) assert_stat_op_api('mean', float_frame, float_string_frame) - def test_mean_mixed_datetime_numeric(self): + @pytest.mark.parametrize('tz', [None, 'UTC']) + def test_mean_mixed_datetime_numeric(self, tz): # https://github.com/pandas-dev/pandas/issues/24752 - df = pd.DataFrame({"A": [1, 1], "B": [pd.Timestamp('2000')] * 2}) + df = pd.DataFrame({"A": [1, 1], + "B": [pd.Timestamp('2000', tz=tz)] * 2}) result = df.mean() expected = pd.Series([1.0], index=['A']) tm.assert_series_equal(result, expected) - def test_mean_excludeds_datetimes(self): + @pytest.mark.parametrize('tz', [None, 'UTC']) + def test_mean_excludeds_datetimes(self, tz): # https://github.com/pandas-dev/pandas/issues/24752 # Our long-term desired behavior is unclear, but the behavior in # 0.24.0rc1 was buggy. - df = pd.DataFrame({"A": [pd.Timestamp('2000')] * 2}) + df = pd.DataFrame({"A": [pd.Timestamp('2000', tz=tz)] * 2}) result = df.mean() expected = pd.Series() tm.assert_series_equal(result, expected)