diff --git a/doc/source/v0.14.1.txt b/doc/source/v0.14.1.txt index aacc4ae989611..c92e853ad8317 100644 --- a/doc/source/v0.14.1.txt +++ b/doc/source/v0.14.1.txt @@ -219,6 +219,8 @@ Bug Fixes 1-dimensional ``nan`` arrays (:issue:`7354`) - Bug where ``nanops.nanmedian`` doesn't work when ``axis==None`` (:issue:`7352`) +- Bug where ``nanops._has_infs`` doesn't work with many dtypes + (:issue:`7357`) diff --git a/pandas/core/nanops.py b/pandas/core/nanops.py index 4b78164003eed..c3e1da61330fa 100644 --- a/pandas/core/nanops.py +++ b/pandas/core/nanops.py @@ -105,14 +105,18 @@ def _bn_ok_dtype(dt, name): return True return False + def _has_infs(result): if isinstance(result, np.ndarray): if result.dtype == 'f8': - return lib.has_infs_f8(result) + return lib.has_infs_f8(result.ravel()) elif result.dtype == 'f4': - return lib.has_infs_f4(result) + return lib.has_infs_f4(result.ravel()) + try: + return np.isinf(result).any() + except (TypeError, NotImplementedError) as e: + # if it doesn't support infs, then it can't have infs return False - return np.isinf(result) or np.isneginf(result) def _get_fill_value(dtype, fill_value=None, fill_value_typ=None): @@ -538,18 +542,20 @@ def _maybe_arg_null_out(result, axis, mask, skipna): def _get_counts(mask, axis): - if axis is not None: - count = (mask.shape[axis] - mask.sum(axis)).astype(float) - else: - count = float(mask.size - mask.sum()) + if axis is None: + return float(mask.size - mask.sum()) - return count + count = mask.shape[axis] - mask.sum(axis) + try: + return count.astype(float) + except AttributeError: + return np.array(count, dtype=float) def _maybe_null_out(result, axis, mask): if axis is not None and getattr(result, 'ndim', False): null_mask = (mask.shape[axis] - mask.sum(axis)) == 0 - if null_mask.any(): + if np.any(null_mask): if np.iscomplexobj(result): result = result.astype('c16') else: @@ -638,8 +644,16 @@ def nancov(a, b, min_periods=None): def _ensure_numeric(x): if isinstance(x, np.ndarray): - if x.dtype == np.object_: + if x.dtype.kind in ['i', 'b']: x = x.astype(np.float64) + elif x.dtype == np.object_: + try: + x = x.astype(np.complex128) + except: + x = x.astype(np.float64) + else: + if not np.any(x.imag): + x = x.real elif not (com.is_float(x) or com.is_integer(x) or com.is_complex(x)): try: x = float(x) diff --git a/pandas/tests/test_nanops.py b/pandas/tests/test_nanops.py index 118ccf0141225..417cef92412b1 100644 --- a/pandas/tests/test_nanops.py +++ b/pandas/tests/test_nanops.py @@ -597,25 +597,27 @@ def check_bool(self, func, value, correct, *args, **kwargs): break def test__has_infs(self): - pairs = [('arr_complex_1d', False), - ('arr_int_1d', False), - ('arr_bool_1d', False), - ('arr_str_1d', False), - ('arr_utf_1d', False), - ('arr_complex_1d', False), - ('arr_complex_nan_1d', False), - - ('arr_nan_nanj_1d', False)] - pairs_float = [('arr_float_1d', False), - ('arr_nan_1d', False), - ('arr_float_nan_1d', False), - ('arr_nan_nan_1d', False), - - ('arr_float_inf_1d', True), - ('arr_inf_1d', True), - ('arr_nan_inf_1d', True), - ('arr_float_nan_inf_1d', True), - ('arr_nan_nan_inf_1d', True)] + pairs = [('arr_complex', False), + ('arr_int', False), + ('arr_bool', False), + ('arr_str', False), + ('arr_utf', False), + ('arr_complex', False), + ('arr_complex_nan', False), + + ('arr_nan_nanj', False), + ('arr_nan_infj', True), + ('arr_complex_nan_infj', True)] + pairs_float = [('arr_float', False), + ('arr_nan', False), + ('arr_float_nan', False), + ('arr_nan_nan', False), + + ('arr_float_inf', True), + ('arr_inf', True), + ('arr_nan_inf', True), + ('arr_float_nan_inf', True), + ('arr_nan_nan_inf', True)] for arr, correct in pairs: val = getattr(self, arr) @@ -630,6 +632,7 @@ def test__has_infs(self): try: self.check_bool(nanops._has_infs, val, correct) self.check_bool(nanops._has_infs, val.astype('f4'), correct) + self.check_bool(nanops._has_infs, val.astype('f2'), correct) except BaseException as exc: exc.args += (arr,) raise