Skip to content

Commit db90bbb

Browse files
jbrockmendelphofl
authored andcommitted
BUG: Index[object].astype(td64) failing to raise with invalid NAs (pandas-dev#45722)
1 parent f2d64d7 commit db90bbb

File tree

3 files changed

+22
-5
lines changed

3 files changed

+22
-5
lines changed

doc/source/whatsnew/v1.5.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ Datetimelike
222222
- Bug in :meth:`DataFrame.quantile` with datetime-like dtypes and no rows incorrectly returning ``float64`` dtype instead of retaining datetime-like dtype (:issue:`41544`)
223223
- Bug in :func:`to_datetime` with sequences of ``np.str_`` objects incorrectly raising (:issue:`32264`)
224224
- Bug in :class:`Timestamp` construction when passing datetime components as positional arguments and ``tzinfo`` as a keyword argument incorrectly raising (:issue:`31929`)
225+
- Bug in :meth:`Index.astype` when casting from object dtype to ``timedelta64[ns]`` dtype incorrectly casting ``np.datetime64("NaT")`` values to ``np.timedelta64("NaT")`` instead of raising (:issue:`45722`)
225226
-
226227

227228
Timedelta

pandas/core/dtypes/astype.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import numpy as np
1616

1717
from pandas._libs import lib
18+
from pandas._libs.tslibs.timedeltas import array_to_timedelta64
1819
from pandas._typing import (
1920
ArrayLike,
2021
DtypeObj,
@@ -139,7 +140,7 @@ def astype_nansafe(
139140
elif is_object_dtype(arr.dtype):
140141

141142
# work around NumPy brokenness, #1987
142-
if np.issubdtype(dtype.type, np.integer):
143+
if dtype.kind in ["i", "u"]:
143144
return lib.astype_intsafe(arr, dtype)
144145

145146
# if we have a datetime/timedelta array of objects
@@ -154,9 +155,10 @@ def astype_nansafe(
154155
copy=copy,
155156
)
156157
elif is_timedelta64_dtype(dtype):
157-
from pandas import to_timedelta
158-
159-
return astype_nansafe(to_timedelta(arr)._values, dtype, copy=copy)
158+
# bc we know arr.dtype == object, this is equivalent to
159+
# `np.asarray(to_timedelta(arr))`, but using a lower-level API that
160+
# does not require a circular import.
161+
return array_to_timedelta64(arr).view("m8[ns]").astype(dtype, copy=False)
160162

161163
if dtype.name in ("datetime64", "timedelta64"):
162164
msg = (

pandas/tests/indexes/object/test_astype.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,9 @@
1-
from pandas import Index
1+
import pytest
2+
3+
from pandas import (
4+
Index,
5+
NaT,
6+
)
27
import pandas._testing as tm
38

49

@@ -8,3 +13,12 @@ def test_astype_str_from_bytes():
813
result = idx.astype(str)
914
expected = Index(["あ", "a"], dtype="object")
1015
tm.assert_index_equal(result, expected)
16+
17+
18+
def test_astype_invalid_nas_to_tdt64_raises():
19+
# GH#45722 don't cast np.datetime64 NaTs to timedelta64 NaT
20+
idx = Index([NaT.asm8] * 2, dtype=object)
21+
22+
msg = r"Cannot cast Index to dtype timedelta64\[ns\]"
23+
with pytest.raises(TypeError, match=msg):
24+
idx.astype("m8[ns]")

0 commit comments

Comments
 (0)