@@ -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 )
499459cdef int64_t parse_timedelta_string(str ts) except ? - 1 :
500460 """
0 commit comments