Skip to content

Commit 7a880ec

Browse files
committed
REF: prepare array_to_timedelta64 for inference
1 parent ebbd16c commit 7a880ec

File tree

1 file changed

+18
-58
lines changed

1 file changed

+18
-58
lines changed

pandas/_libs/tslibs/timedeltas.pyx

Lines changed: 18 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -408,10 +408,11 @@ def array_to_timedelta64(
408408
cdef:
409409
Py_ssize_t i, n = values.size
410410
ndarray result = np.empty((<object>values).shape, dtype="m8[ns]")
411-
object item
411+
object item, td64ns_obj
412412
int64_t ival
413413
cnp.broadcast mi = cnp.PyArray_MultiIterNew2(result, values)
414414
cnp.flatiter it
415+
str parsed_unit = parse_timedelta_unit(unit or "ns")
415416

416417
if values.descr.type_num != cnp.NPY_OBJECT:
417418
# raise here otherwise we segfault below
@@ -431,70 +432,29 @@ def array_to_timedelta64(
431432
)
432433
cnp.PyArray_ITER_NEXT(it)
433434

434-
# Usually, we have all strings. If so, we hit the fast path.
435-
# If this path fails, we try conversion a different way, and
436-
# this is where all of the error handling will take place.
437-
try:
438-
for i in range(n):
439-
# Analogous to: item = values[i]
440-
item = <object>(<PyObject**>cnp.PyArray_MultiIter_DATA(mi, 1))[0]
441-
442-
ival = _item_to_timedelta64_fastpath(item)
443-
444-
# Analogous to: iresult[i] = ival
445-
(<int64_t*>cnp.PyArray_MultiIter_DATA(mi, 0))[0] = ival
446-
447-
cnp.PyArray_MultiIter_NEXT(mi)
448-
449-
except (TypeError, ValueError):
450-
cnp.PyArray_MultiIter_RESET(mi)
451-
452-
parsed_unit = parse_timedelta_unit(unit or "ns")
453-
for i in range(n):
454-
item = <object>(<PyObject**>cnp.PyArray_MultiIter_DATA(mi, 1))[0]
435+
for i in range(n):
436+
item = <object>(<PyObject**>cnp.PyArray_MultiIter_DATA(mi, 1))[0]
455437

456-
ival = _item_to_timedelta64(item, parsed_unit, errors)
438+
try:
439+
td64ns_obj = convert_to_timedelta64(item, parsed_unit)
440+
ival = cnp.get_timedelta64_value(td64ns_obj)
441+
except ValueError as err:
442+
if errors == "coerce":
443+
ival = NPY_NAT
444+
elif "unit abbreviation w/o a number" in str(err):
445+
# re-raise with more pertinent message
446+
msg = f"Could not convert '{item}' to NumPy timedelta"
447+
raise ValueError(msg) from err
448+
else:
449+
raise
457450

458-
(<int64_t*>cnp.PyArray_MultiIter_DATA(mi, 0))[0] = ival
451+
(<int64_t*>cnp.PyArray_MultiIter_DATA(mi, 0))[0] = ival
459452

460-
cnp.PyArray_MultiIter_NEXT(mi)
453+
cnp.PyArray_MultiIter_NEXT(mi)
461454

462455
return result
463456

464457

465-
cdef int64_t _item_to_timedelta64_fastpath(object item) except? -1:
466-
"""
467-
See array_to_timedelta64.
468-
"""
469-
if item is NaT:
470-
# we allow this check in the fast-path because NaT is a C-object
471-
# so this is an inexpensive check
472-
return NPY_NAT
473-
else:
474-
return parse_timedelta_string(item)
475-
476-
477-
cdef int64_t _item_to_timedelta64(
478-
object item,
479-
str parsed_unit,
480-
str errors
481-
) except? -1:
482-
"""
483-
See array_to_timedelta64.
484-
"""
485-
try:
486-
return cnp.get_timedelta64_value(convert_to_timedelta64(item, parsed_unit))
487-
except ValueError as err:
488-
if errors == "coerce":
489-
return NPY_NAT
490-
elif "unit abbreviation w/o a number" in str(err):
491-
# re-raise with more pertinent message
492-
msg = f"Could not convert '{item}' to NumPy timedelta"
493-
raise ValueError(msg) from err
494-
else:
495-
raise
496-
497-
498458
@cython.cpow(True)
499459
cdef int64_t parse_timedelta_string(str ts) except? -1:
500460
"""

0 commit comments

Comments
 (0)