Skip to content

Commit 9659602

Browse files
committed
Merge pull request #7448 from toddrjen/naninf
Fix bug where ``nanops._has_infs`` doesn't work with many dtypes (issue #7357)
2 parents 818cf27 + b679189 commit 9659602

File tree

3 files changed

+48
-29
lines changed

3 files changed

+48
-29
lines changed

doc/source/v0.14.1.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -217,6 +217,8 @@ Bug Fixes
217217
1-dimensional ``nan`` arrays (:issue:`7354`)
218218
- Bug where ``nanops.nanmedian`` doesn't work when ``axis==None``
219219
(:issue:`7352`)
220+
- Bug where ``nanops._has_infs`` doesn't work with many dtypes
221+
(:issue:`7357`)
220222

221223

222224

pandas/core/nanops.py

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -105,14 +105,18 @@ def _bn_ok_dtype(dt, name):
105105
return True
106106
return False
107107

108+
108109
def _has_infs(result):
109110
if isinstance(result, np.ndarray):
110111
if result.dtype == 'f8':
111-
return lib.has_infs_f8(result)
112+
return lib.has_infs_f8(result.ravel())
112113
elif result.dtype == 'f4':
113-
return lib.has_infs_f4(result)
114+
return lib.has_infs_f4(result.ravel())
115+
try:
116+
return np.isinf(result).any()
117+
except (TypeError, NotImplementedError) as e:
118+
# if it doesn't support infs, then it can't have infs
114119
return False
115-
return np.isinf(result) or np.isneginf(result)
116120

117121

118122
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):
538542

539543

540544
def _get_counts(mask, axis):
541-
if axis is not None:
542-
count = (mask.shape[axis] - mask.sum(axis)).astype(float)
543-
else:
544-
count = float(mask.size - mask.sum())
545+
if axis is None:
546+
return float(mask.size - mask.sum())
545547

546-
return count
548+
count = mask.shape[axis] - mask.sum(axis)
549+
try:
550+
return count.astype(float)
551+
except AttributeError:
552+
return np.array(count, dtype=float)
547553

548554

549555
def _maybe_null_out(result, axis, mask):
550556
if axis is not None and getattr(result, 'ndim', False):
551557
null_mask = (mask.shape[axis] - mask.sum(axis)) == 0
552-
if null_mask.any():
558+
if np.any(null_mask):
553559
if np.iscomplexobj(result):
554560
result = result.astype('c16')
555561
else:
@@ -638,8 +644,16 @@ def nancov(a, b, min_periods=None):
638644

639645
def _ensure_numeric(x):
640646
if isinstance(x, np.ndarray):
641-
if x.dtype == np.object_:
647+
if x.dtype.kind in ['i', 'b']:
642648
x = x.astype(np.float64)
649+
elif x.dtype == np.object_:
650+
try:
651+
x = x.astype(np.complex128)
652+
except:
653+
x = x.astype(np.float64)
654+
else:
655+
if not np.any(x.imag):
656+
x = x.real
643657
elif not (com.is_float(x) or com.is_integer(x) or com.is_complex(x)):
644658
try:
645659
x = float(x)

pandas/tests/test_nanops.py

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -597,25 +597,27 @@ def check_bool(self, func, value, correct, *args, **kwargs):
597597
break
598598

599599
def test__has_infs(self):
600-
pairs = [('arr_complex_1d', False),
601-
('arr_int_1d', False),
602-
('arr_bool_1d', False),
603-
('arr_str_1d', False),
604-
('arr_utf_1d', False),
605-
('arr_complex_1d', False),
606-
('arr_complex_nan_1d', False),
607-
608-
('arr_nan_nanj_1d', False)]
609-
pairs_float = [('arr_float_1d', False),
610-
('arr_nan_1d', False),
611-
('arr_float_nan_1d', False),
612-
('arr_nan_nan_1d', False),
613-
614-
('arr_float_inf_1d', True),
615-
('arr_inf_1d', True),
616-
('arr_nan_inf_1d', True),
617-
('arr_float_nan_inf_1d', True),
618-
('arr_nan_nan_inf_1d', True)]
600+
pairs = [('arr_complex', False),
601+
('arr_int', False),
602+
('arr_bool', False),
603+
('arr_str', False),
604+
('arr_utf', False),
605+
('arr_complex', False),
606+
('arr_complex_nan', False),
607+
608+
('arr_nan_nanj', False),
609+
('arr_nan_infj', True),
610+
('arr_complex_nan_infj', True)]
611+
pairs_float = [('arr_float', False),
612+
('arr_nan', False),
613+
('arr_float_nan', False),
614+
('arr_nan_nan', False),
615+
616+
('arr_float_inf', True),
617+
('arr_inf', True),
618+
('arr_nan_inf', True),
619+
('arr_float_nan_inf', True),
620+
('arr_nan_nan_inf', True)]
619621

620622
for arr, correct in pairs:
621623
val = getattr(self, arr)
@@ -630,6 +632,7 @@ def test__has_infs(self):
630632
try:
631633
self.check_bool(nanops._has_infs, val, correct)
632634
self.check_bool(nanops._has_infs, val.astype('f4'), correct)
635+
self.check_bool(nanops._has_infs, val.astype('f2'), correct)
633636
except BaseException as exc:
634637
exc.args += (arr,)
635638
raise

0 commit comments

Comments
 (0)