Skip to content

Commit ea2b810

Browse files
jbrockmendelquintusdias
authored andcommitted
stop conflating iNaT with td64-NaT (pandas-dev#27411)
1 parent 17a5d49 commit ea2b810

File tree

3 files changed

+20
-16
lines changed

3 files changed

+20
-16
lines changed

pandas/core/internals/blocks.py

+7-14
Original file line numberDiff line numberDiff line change
@@ -2607,6 +2607,7 @@ class TimeDeltaBlock(DatetimeLikeBlockMixin, IntBlock):
26072607
is_timedelta = True
26082608
_can_hold_na = True
26092609
is_numeric = False
2610+
fill_value = np.timedelta64("NaT", "ns")
26102611

26112612
def __init__(self, values, placement, ndim=None):
26122613
if values.dtype != _TD_DTYPE:
@@ -2627,15 +2628,11 @@ def _box_func(self):
26272628
def _can_hold_element(self, element):
26282629
tipo = maybe_infer_dtype_type(element)
26292630
if tipo is not None:
2630-
# TODO: remove the np.int64 support once coerce_values and
2631-
# _try_coerce_args both coerce to m8[ns] and not i8.
2632-
return issubclass(tipo.type, (np.timedelta64, np.int64))
2631+
return issubclass(tipo.type, np.timedelta64)
26332632
elif element is NaT:
26342633
return True
26352634
elif isinstance(element, (timedelta, np.timedelta64)):
26362635
return True
2637-
elif is_integer(element):
2638-
return element == tslibs.iNaT
26392636
return is_valid_nat_for_dtype(element, self.dtype)
26402637

26412638
def fillna(self, value, **kwargs):
@@ -2655,9 +2652,6 @@ def fillna(self, value, **kwargs):
26552652
value = Timedelta(value, unit="s")
26562653
return super().fillna(value, **kwargs)
26572654

2658-
def _coerce_values(self, values):
2659-
return values.view("i8")
2660-
26612655
def _try_coerce_args(self, other):
26622656
"""
26632657
Coerce values and other to int64, with null values converted to
@@ -2673,13 +2667,12 @@ def _try_coerce_args(self, other):
26732667
"""
26742668

26752669
if is_valid_nat_for_dtype(other, self.dtype):
2676-
other = tslibs.iNaT
2677-
elif is_integer(other) and other == tslibs.iNaT:
2678-
pass
2670+
other = np.timedelta64("NaT", "ns")
26792671
elif isinstance(other, (timedelta, np.timedelta64)):
2680-
other = Timedelta(other).value
2672+
other = Timedelta(other).to_timedelta64()
26812673
elif hasattr(other, "dtype") and is_timedelta64_dtype(other):
2682-
other = other.astype("i8", copy=False).view("i8")
2674+
# TODO: can we get here with non-nano dtype?
2675+
pass
26832676
else:
26842677
# coercion issues
26852678
# let higher levels handle
@@ -2693,7 +2686,7 @@ def _try_coerce_result(self, result):
26932686
mask = isna(result)
26942687
if result.dtype.kind in ["i", "f"]:
26952688
result = result.astype("m8[ns]")
2696-
result[mask] = tslibs.iNaT
2689+
result[mask] = np.timedelta64("NaT", "ns")
26972690

26982691
elif isinstance(result, (np.integer, np.float)):
26992692
result = self._box_func(result)

pandas/core/nanops.py

+8
Original file line numberDiff line numberDiff line change
@@ -1360,6 +1360,14 @@ def _nanpercentile_1d(values, mask, q, na_value, interpolation):
13601360
quantiles : scalar or array
13611361
"""
13621362
# mask is Union[ExtensionArray, ndarray]
1363+
if values.dtype.kind == "m":
1364+
# need to cast to integer to avoid rounding errors in numpy
1365+
result = _nanpercentile_1d(values.view("i8"), mask, q, na_value, interpolation)
1366+
1367+
# Note: we have to do do `astype` and not view because in general we
1368+
# have float result at this point, not i8
1369+
return result.astype(values.dtype)
1370+
13631371
values = values[~mask]
13641372

13651373
if len(values) == 0:

pandas/tests/series/test_missing.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -791,9 +791,11 @@ def test_timedelta64_nan(self):
791791
td1[0] = td[0]
792792
assert not isna(td1[0])
793793

794+
# GH#16674 iNaT is treated as an integer when given by the user
794795
td1[1] = iNaT
795-
assert isna(td1[1])
796-
assert td1[1].value == iNaT
796+
assert not isna(td1[1])
797+
assert td1.dtype == np.object_
798+
assert td1[1] == iNaT
797799
td1[1] = td[1]
798800
assert not isna(td1[1])
799801

@@ -803,6 +805,7 @@ def test_timedelta64_nan(self):
803805
td1[2] = td[2]
804806
assert not isna(td1[2])
805807

808+
# FIXME: don't leave commented-out
806809
# boolean setting
807810
# this doesn't work, not sure numpy even supports it
808811
# result = td[(td>np.timedelta64(timedelta(days=3))) &

0 commit comments

Comments
 (0)