8000 BUG: Fix np.lib.nanfunctions on object arrays by eric-wieser · Pull Request #9013 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

BUG: Fix np.lib.nanfunctions on object arrays #9013

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 29, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 19 additions & 15 deletions numpy/lib/nanfunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,17 +61,19 @@ def _replace_nan(a, val):
NaNs, otherwise return None.

"""
is_new = not isinstance(a, np.ndarray)
if is_new:
a = np.array(a)
if not issubclass(a.dtype.type, np.inexact):
return a, None
if not is_new:
# need copy
a = np.array(a, subok=True)

mask = np.isnan(a)
np.copyto(a, val, where=mask)
a = np.array(a, subok=True, copy=True)

if a.dtype == np.object_:
# object arrays do not support `isnan` (gh-9009), so make a guess
mask = a != a
elif issubclass(a.dtype.type, np.inexact):
mask = np.isnan(a)
else:
mask = None

if mask is not None:
np.copyto(a, val, where=mask)

return a, mask


Expand Down Expand Up @@ -232,8 +234,9 @@ def nanmin(a, axis=None, out=None, keepdims=np._NoValue):
kwargs = {}
if keepdims is not np._NoValue:
kwargs['keepdims'] = keepdims
if not isinstance(a, np.ndarray) or type(a) is np.ndarray:
# Fast, but not safe for subclasses of ndarray
if type(a) is np.ndarray and a.dtype != np.object_:
# Fast, but not safe for subclasses of ndarray, or object arrays,
# which do not implement isnan (gh-9009), or fmin correctly (gh-8975)
res = np.fmin.reduce(a, axis=axis, out=out, **kwargs)
if np.isnan(res).any():
warnings.warn("All-NaN axis encountered", RuntimeWarning, stacklevel=2)
Expand Down Expand Up @@ -339,8 +342,9 @@ def nanmax(a, axis=None, out=None, keepdims=np._NoValue):
kwargs = {}
if keepdims is not np._NoValue:
kwargs['keepdims'] = keepdims
if not isinstance(a, np.ndarray) or type(a) is np.ndarray:
# Fast, but not safe for subclasses of ndarray
if type(a) is np.ndarray and a.dtype != np.object_:
# Fast, but not safe for subclasses of ndarray, or object arrays,
# which do not implement isnan (gh-9009), or fmax correctly (gh-8975)
res = np.fmax.reduce(a, axis=axis, out=out, **kwargs)
if np.isnan(res).any():
warnings.warn("All-NaN slice encountered", RuntimeWarning, stacklevel=2)
Expand Down
12 changes: 12 additions & 0 deletions numpy/lib/tests/test_nanfunctions.py
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,18 @@ def test_matrices(self):
assert_(res != np.nan)
assert_(len(w) == 0)

def test_object_array(self):
arr = np.array([[1.0, 2.0], [np.nan, 4.0], [np.nan, np.nan]], dtype=object)
assert_equal(np.nanmin(arr), 1.0)
assert_equal(np.nanmin(arr, axis=0), [1.0, 2.0])

with warnings.catch_warnings(record=True) as w:
warnings.simplefilter('always')
# assert_equal does not work on object arrays of nan
assert_equal(list(np.nanmin(arr, axis=1)), [1.0, 4.0, np.nan])
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More details at #9023

assert_(len(w) == 1, 'no warning raised')
assert_(issubclass(w[0].category, RuntimeWarning))


class TestNanFunctions_ArgminArgmax(TestCase):

Expand Down
0