From b59d06c7b411c10324c29be13b34886b150664d4 Mon Sep 17 00:00:00 2001 From: Jeff Reback Date: Wed, 16 Sep 2015 16:27:43 -0700 Subject: [PATCH] ERR: make sure raising TypeError on invalid nanops reductions xref #10472 --- doc/source/whatsnew/v0.17.0.txt | 1 + pandas/core/nanops.py | 24 +++++++++++++++++++++--- pandas/tests/test_frame.py | 2 +- pandas/tests/test_series.py | 4 ++++ 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/doc/source/whatsnew/v0.17.0.txt b/doc/source/whatsnew/v0.17.0.txt index 3d625c0299db5..622324155b551 100644 --- a/doc/source/whatsnew/v0.17.0.txt +++ b/doc/source/whatsnew/v0.17.0.txt @@ -915,6 +915,7 @@ Other API Changes - ``groupby`` using ``Categorical`` follows the same rule as ``Categorical.unique`` described above (:issue:`10508`) - When constructing ``DataFrame`` with an array of ``complex64`` dtype previously meant the corresponding column was automatically promoted to the ``complex128`` dtype. Pandas will now preserve the itemsize of the input for complex data (:issue:`10952`) +- some numeric reduction operators would return ``ValueError``, rather than ``TypeError`` on object types that includes strings and numbers (:issue:`11131`) - ``NaT``'s methods now either raise ``ValueError``, or return ``np.nan`` or ``NaT`` (:issue:`9513`) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 8602fdc26d6f6..1561c0aefbb9b 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -43,7 +43,16 @@ def _f(*args, **kwargs): raise TypeError('reduction operation {0!r} not allowed for ' 'this dtype'.format(f.__name__.replace('nan', ''))) - return f(*args, **kwargs) + try: + return f(*args, **kwargs) + except ValueError as e: + # we want to transform an object array + # ValueError message to the more typical TypeError + # e.g. this is normally a disallowed function on + # object arrays that contain strings + if is_object_dtype(args[0]): + raise TypeError(e) + raise return _f @@ -93,7 +102,17 @@ def f(values, axis=None, skipna=True, **kwds): else: result = alt(values, axis=axis, skipna=skipna, **kwds) except Exception: - result = alt(values, axis=axis, skipna=skipna, **kwds) + try: + result = alt(values, axis=axis, skipna=skipna, **kwds) + except ValueError as e: + # we want to transform an object array + # ValueError message to the more typical TypeError + # e.g. this is normally a disallowed function on + # object arrays that contain strings + + if is_object_dtype(values): + raise TypeError(e) + raise return result @@ -372,7 +391,6 @@ def nanvar(values, axis=None, skipna=True, ddof=1): values = values.copy() np.putmask(values, mask, 0) - # xref GH10242 # Compute variance via two-pass algorithm, which is stable against # cancellation errors and relatively accurate for small numbers of diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index 24de36d95794c..01ad4992dd785 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -12792,7 +12792,7 @@ def test_numeric_only_flag(self): # df1 has all numbers, df2 has a letter inside self.assertRaises(TypeError, lambda : getattr(df1, meth)(axis=1, numeric_only=False)) - self.assertRaises(ValueError, lambda : getattr(df2, meth)(axis=1, numeric_only=False)) + self.assertRaises(TypeError, lambda : getattr(df2, meth)(axis=1, numeric_only=False)) def test_sem(self): alt = lambda x: np.std(x, ddof=1)/np.sqrt(len(x)) diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py index d25009171afdf..7fb89b30cec97 100644 --- a/pandas/tests/test_series.py +++ b/pandas/tests/test_series.py @@ -2912,6 +2912,10 @@ def testit(): exp = alternate(s) self.assertEqual(res, exp) + # check on string data + if name not in ['sum','min','max']: + self.assertRaises(TypeError, f, Series(list('abc'))) + # Invalid axis. self.assertRaises(ValueError, f, self.series, axis=1)