-
-
Notifications
You must be signed in to change notification settings - Fork 10.9k
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
Conversation
025cf09
to
0040d3e
Compare
In light of the failure of gh-14800, we should make sure this PR does not cause problems on pandas. |
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:
|
numpy/testing/_private/utils.py
Outdated
except (TypeError, ValueError, NotImplementedError): | ||
except (TypeError, ValueError, NotImplementedError, DeprecationWarning): |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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)?
0040d3e
to
259b6e3
Compare
numpygh-14841 failed to pass shippable tests, the CI could not install gfortran. We may need to add apt update before apt install.
Thanks! Note that import numpy as np
a = np.array(['1999-12-15', 'NaT'], dtype='M8[ns]')
np.nanmax(a)
np.nanmin(a) Both return |
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. |
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`` |
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fixing
numpy/testing/_private/utils.py
Outdated
# 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. |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
if (array_actual.dtype.char in 'Mm' or | ||
array_desired.dtype.char in 'Mm'): |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, fixing
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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
c5662d2
to
3483f80
Compare
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
|
``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- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
``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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
`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 |
7fdcce7
to
2e25313
Compare
There was a problem hiding this 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.
There was a problem hiding this 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.
Co-Authored-By: Warren Weckesser <warren.weckesser@gmail.com>
Co-Authored-By: Warren Weckesser <warren.weckesser@gmail.com>
Fixes gh-14831.
Changes behavior. Previously
isnan
,isinf
were unavailable fordatetime64
dtypes. Nowassert_equal
behaves slightly differently. Previouslyassert_equal(a, b)
would raise ifa
andb
containedNaT
in the same position. NowNaT
is equivalent tofloat('nan')
and the call passes. I think this is consistent with the function docstring: