8000 ENH: add isinf, isnan, fmin, fmax loops for datetime64, timedelta64 by mattip · Pull Request #14841 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

ENH: add isinf, isnan, fmin, fmax loops for datetime64, timedelta64 #14841

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 10 commits into from
Nov 22, 2019

Conversation

mattip
Copy link
Member
@mattip mattip commented Nov 6, 2019

Fixes gh-14831.

Changes behavior. Previously isnan, isinf were unavailable for datetime64 dtypes. Now assert_equal behaves slightly differently. Previously assert_equal(a, b) would raise if a and b contained NaT in the same position. Now NaT is equivalent to float('nan') and the call passes. I think this is consistent with the function docstring:

This function handles NaN comparisons as if NaN was a "normal" number.
That is, no assertion is raised if both objects have NaNs in the same
positions. This is in contrast to the IEEE standard on NaNs, which says
that NaN compared to anything must return False.

@mattip mattip added 01 - Enhancement 56 - Needs Release Note. Needs an entry in doc/release/upcoming_changes labels Nov 6, 2019
@mattip
Copy link
Member Author
mattip commented Nov 6, 2019

In light of the failure of gh-14800, we should make sure this PR does not cause problems on pandas.

@mattip
Copy link
Member Author
mattip commented Nov 6, 2019

Tested this against pandas 0.25.3. Some tests will need adjustment since now they do not raise, but it did not seem to cause new failures:

FAILED pandas/tests/indexes/test_numpy_compat.py::test_numpy_ufuncs_other[DatetimeIndex-isinf] - Failed: DID NOT RAISE <class 'Except...
FAILED pandas/tests/indexes/test_numpy_compat.py::test_numpy_ufuncs_other[DatetimeIndex-isnan] - Failed: DID NOT RAISE <class 'Except...
FAILED pandas/tests/indexes/test_numpy_compat.py::test_numpy_ufuncs_other[TimedeltaIndex-isinf] - Failed: DID NOT RAISE <class 'Excep...
FAILED pandas/tests/indexes/test_numpy_compat.py::test_numpy_ufuncs_other[TimedeltaIndex-isnan] - Failed: DID NOT RAISE <class 'Excep...

8000
except (TypeError, ValueError, NotImplementedError):
except (TypeError, ValueError, NotImplementedError, DeprecationWarning):
Copy link
Member

Choose a reason for hiding this comment

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

This seems risky, and at least deserving of a source comment.

Copy link
Member Author

Choose a reason for hiding this comment

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

Added an explanation and a version changed

Copy link
Member

Choose a reason for hiding this comment

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

It's tempting to add an entirely separate except DeprecationWarning with this comment

Copy link
Member

Choose a reason for hiding this comment

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

Thinking some more, we should not be catching warnings as exceptions at all - shouldn't we be suppressing them even if they're not exceptions (or not suppressing them at all)?

@dcherian dcherian mentioned this pull request Nov 7, 2019
12 tasks
@mattip mattip removed the 56 - Needs Release Note. Needs an entry in doc/release/upcoming_changes label Nov 7, 2019
charris added a commit to charris/numpy that referenced this pull request Nov 7, 2019
numpygh-14841 failed to pass shippable tests, the CI could not install
gfortran. We may need to add apt update before apt install.
@mathause
Copy link
mathause commented Nov 8, 2019

Thanks! Note that nanmax and nanmin don't return the correct result, even after this change (due to #8975 ?) :

import numpy as np
a = np.array(['1999-12-15', 'NaT'], dtype='M8[ns]')
np.nanmax(a) 
np.nanmin(a)

Both return numpy.datetime64('NaT') Does this belong here or in a separate issue?

@mattip
Copy link
Member Author
mattip commented Nov 8, 2019

the issue is that fmin, fmax are mapped to minimum, maximum when they should have unique loops to scan for NaT. I can add it to this PR.

@mattip mattip changed the title ENH: add isinf, isnan for datetine64, timedelta64 ENH: add isinf, isnan, fmin, fmax loops for datetine64, timedelta64 Nov 8, 2019
facing code. Specifically, code that either disallowed the calls to `isinf`` or
``isnan`` or checked that they raised an exception will require adaptation, and
code that mistakenly called ``fmax`` and ``fmin`` instead of ``maximum`` or
``minimum`` respectively will requre adjustment. This also affects ``nanmax``
Copy link

Choose a reason for hiding this comment

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

I think nanmax raised before 1.18. (Or maybe I missunderstand this comment).

Copy link
Member Author

Choose a reason for hiding this comment

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

fixing

@eric-wieser eric-wieser changed the title ENH: add isinf, isnan, fmin, fmax loops for datetine64, timedelta64 ENH: add isinf, isnan, fmin, fmax loops for datetime64, timedelta64 Nov 11, 2019
@eric-wieser eric-wieser added the component: numpy.datetime64 (and timedelta64) label Nov 11, 2019
# version 1.18
# gisnan used to raise for datetime64/timedelta64 (dt64) since they had
# no isnan implementation. That call no longer raises. However, a
# DeprecationWarning is raised when comparing dt64 to 0.
Copy link
Member

Choose a reason for hiding this comment

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

this comment still applies - this will still emit noisy warnings if I don't have warnings set to raise - we should either:

  • Suppress warnings, rather than catching them
  • Locally promote warnings to raise
  • Special case datetime types to avoid this path
  • Call cancast somehow to avoid this path

Copy link
Member Author

Choose a reason for hiding this comment

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

special casing seems like the easiest

Comment on lines +402 to +403
if (array_actual.dtype.char in 'Mm' or
array_desired.dtype.char in 'Mm'):
Copy link
Member

Choose a reason for hiding this comment

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

You only want M here, not m

Copy link
Member Author

Choose a reason for hiding this comment

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

It doesn't really matter, the test just below this is only for things that will have a signbit on a 0 value, so timedelta64 might as well never go to the next clause

Copy link
Member

Choose a reason for hiding this comment

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

Well at that point you may as well add integers here too - at any rate, the comment is saying "this won't work", not "this is a shortcut to save time".

Copy link
Member Author

Choose a reason for hiding this comment

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

ok, fixing

Copy link
Member Author

Choose a reason for hiding this comment

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

actually, np.timedelta64(7, 's') == 0 emits a DeprecationWarning, so we need both 'Mm', and the comment is wrong

F438

Copy link
Member
@eric-wieser eric-wieser Nov 15, 2019

Choose a reason for hiding this comment

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

Seems weird that td[s] == td is deprecated yet td[s] + td is not - perhaps worth opening a new issue about

@mathause
Copy link

Do you plan to get this into 1.18? I guess this could help external libraries so that they don't have to check for 3 cases

  • before 1.18: min -> value, nanmin -> error
  • after 1.18: min -> NaT, nanmin -> error
  • after this gets merged: min -> NaT, nanmin -> value

``np.datetime('NaT')`` should behave more like ``float('Nan')``. Add needed
infrastructure so ``np.isinf(a)`` and ``np.isnan(a)`` will run on
``datetime64`` and ``timedelta64`` dtypes. Also added specific loops for
``fmin`` and ``fmax`` that mask ``NaT``. This may require adjustment to user-
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
``fmin`` and ``fmax`` that mask ``NaT``. This may require adjustment to user-
`fmin` and `fmax` that mask ``NaT``. This may require adjustment to user-

may as well link these, right?

Copy link
Member Author

Choose a reason for hiding this comment

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

ok

``datetime64`` and ``timedelta64`` dtypes. Also added specific loops for
`numpy.fmin` and `numpy.fmax` that mask ``NaT``. This may require adjustment to user-
facing code. Specifically, code that either disallowed the calls to
`numpy.isinf`` or `numpy.isnan`` or checked that they raised an exception will
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
`numpy.isinf`` or `numpy.isnan`` or checked that they raised an exception will
`numpy.isinf` or `numpy.isnan` or checked that they raised an exception will

Copy link
Member
@WarrenWeckesser WarrenWeckesser left a comment

Choose a reason for hiding this comment

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

Just one change requested. Otherwise LGTM.

Copy link
Member
@WarrenWeckesser WarrenWeckesser left a comment

Choose a reason for hiding this comment

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

I suggested a some tweaks to fix the slightly misleading comment and exception message.

mattip and others added 2 commits November 21, 2019 14:48
Co-Authored-By: Warren Weckesser <warren.weckesser@gmail.com>
Co-Authored-By: Warren Weckesser <warren.weckesser@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

np.isnan raises an error for datetime (NaT)
4 participants
0