-
-
Notifications
You must be signed in to change notification settings - Fork 11.1k
Description
Describe the issue:
The logic for timedelta64
comparisons involving a generic timedelta64 is surprising, and leads to non-transitivity of something that I'd expect to be a total ordering. In the snippet below, x < y
and y < z
are both True
, but x < z
is False
.
>>> import numpy as np
>>> x, y, z = np.timedelta64(1, "ms"), np.timedelta64(2), np.timedelta64(5, "ns")
>>> x < y < z
np.True_
>>> x < z
np.False_
The x < z
result is what I expect. For x < y
and y < z
, I was expecting either a consistent default for the units for y
(though I'm not sure what default I was expecting - any of days / seconds / nanoseconds would seem plausible), or to get an error or warning about an ill-defined comparison.
It appears that the actual behaviour is that y
is interpreted as being in milliseconds for the x < y
comparison, and then in nanoseconds for the y < z
comparison.
The same lack of transitivity applies to equality comparisons:
>>> x, y, z = np.timedelta64(1, "ms"), np.timedelta64(1), np.timedelta64(1, "ns")
>>> x == y == z
np.True_
>>> x == z
np.False_
(Though it looks like we're protected from peculiar dict
/ set
containment consequences by the fact that y
isn't hashable.)
Meta: "BUG" may be a stretch here - I don't doubt that the behaviour described is intentional, but it's still surprising, and as far as I can tell undocumented (I couldn't find any hints to this behaviour at https://numpy.org/doc/stable/reference/arrays.datetime.html). In which case this is at best a doc bug.
Reproduce the code example:
import numpy as np
x, y, z = np.timedelta64(1, "ms"), np.timedelta64(2), np.timedelta64(5, "ns")
print("x < y < z:", x < y < z)
print("x < z:", x < z)
Error message:
Python and NumPy Versions:
NumPy 2.2.2
Python 3.13.1 (main, Dec 7 2024, 10:29:14) [Clang 16.0.0 (clang-1600.0.26.4)]
Runtime Environment:
No response
Context for the issue:
This doesn't affect my work - we've already worked around this issue in our own code. (I think the lesson learned is "to avoid surprises, always provide a unit when using np.timedelta64
".)