Skip to content

Commit 1a7f53a

Browse files
jbrockmendelPingviinituutti
authored andcommitted
REF: Move non-raising parts of array_to_datetime outside of try/except (pandas-dev#24032)
1 parent bdba2cb commit 1a7f53a

File tree

1 file changed

+74
-50
lines changed

1 file changed

+74
-50
lines changed

pandas/_libs/tslib.pyx

+74-50
Original file line numberDiff line numberDiff line change
@@ -520,9 +520,10 @@ cpdef array_to_datetime(ndarray[object] values, str errors='raise',
520520
# specify error conditions
521521
assert is_raise or is_ignore or is_coerce
522522

523+
result = np.empty(n, dtype='M8[ns]')
524+
iresult = result.view('i8')
525+
523526
try:
524-
result = np.empty(n, dtype='M8[ns]')
525-
iresult = result.view('i8')
526527
for i in range(n):
527528
val = values[i]
528529

@@ -703,62 +704,85 @@ cpdef array_to_datetime(ndarray[object] values, str errors='raise',
703704
raise TypeError("{typ} is not convertible to datetime"
704705
.format(typ=type(val)))
705706

706-
if seen_datetime and seen_integer:
707-
# we have mixed datetimes & integers
708-
709-
if is_coerce:
710-
# coerce all of the integers/floats to NaT, preserve
711-
# the datetimes and other convertibles
712-
for i in range(n):
713-
val = values[i]
714-
if is_integer_object(val) or is_float_object(val):
715-
result[i] = NPY_NAT
716-
elif is_raise:
717-
raise ValueError(
718-
"mixed datetimes and integers in passed array")
719-
else:
720-
raise TypeError
721-
722-
if seen_datetime_offset and not utc_convert:
723-
# GH 17697
724-
# 1) If all the offsets are equal, return one offset for
725-
# the parsed dates to (maybe) pass to DatetimeIndex
726-
# 2) If the offsets are different, then force the parsing down the
727-
# object path where an array of datetimes
728-
# (with individual dateutil.tzoffsets) are returned
729-
is_same_offsets = len(out_tzoffset_vals) == 1
730-
if not is_same_offsets:
731-
return array_to_datetime_object(values, is_raise,
732-
dayfirst, yearfirst)
733-
else:
734-
tz_offset = out_tzoffset_vals.pop()
735-
tz_out = pytz.FixedOffset(tz_offset / 60.)
736-
return result, tz_out
737707
except OutOfBoundsDatetime:
738708
if is_raise:
739709
raise
740710

741-
oresult = np.empty(n, dtype=object)
742-
for i in range(n):
743-
val = values[i]
711+
return ignore_errors_out_of_bounds_fallback(values), tz_out
744712

745-
# set as nan except if its a NaT
746-
if checknull_with_nat(val):
747-
if isinstance(val, float):
748-
oresult[i] = np.nan
749-
else:
750-
oresult[i] = NaT
751-
elif is_datetime64_object(val):
752-
if get_datetime64_value(val) == NPY_NAT:
753-
oresult[i] = NaT
754-
else:
755-
oresult[i] = val.item()
756-
else:
757-
oresult[i] = val
758-
return oresult, tz_out
759713
except TypeError:
760714
return array_to_datetime_object(values, is_raise, dayfirst, yearfirst)
761715

716+
if seen_datetime and seen_integer:
717+
# we have mixed datetimes & integers
718+
719+
if is_coerce:
720+
# coerce all of the integers/floats to NaT, preserve
721+
# the datetimes and other convertibles
722+
for i in range(n):
723+
val = values[i]
724+
if is_integer_object(val) or is_float_object(val):
725+
result[i] = NPY_NAT
726+
elif is_raise:
727+
raise ValueError("mixed datetimes and integers in passed array")
728+
else:
729+
return array_to_datetime_object(values, is_raise,
730+
dayfirst, yearfirst)
731+
732+
if seen_datetime_offset and not utc_convert:
733+
# GH#17697
734+
# 1) If all the offsets are equal, return one offset for
735+
# the parsed dates to (maybe) pass to DatetimeIndex
736+
# 2) If the offsets are different, then force the parsing down the
737+
# object path where an array of datetimes
738+
# (with individual dateutil.tzoffsets) are returned
739+
is_same_offsets = len(out_tzoffset_vals) == 1
740+
if not is_same_offsets:
741+
return array_to_datetime_object(values, is_raise,
742+
dayfirst, yearfirst)
743+
else:
744+
tz_offset = out_tzoffset_vals.pop()
745+
tz_out = pytz.FixedOffset(tz_offset / 60.)
746+
return result, tz_out
747+
748+
749+
cdef inline ignore_errors_out_of_bounds_fallback(ndarray[object] values):
750+
"""
751+
Fallback for array_to_datetime if an OutOfBoundsDatetime is raised
752+
and errors == "ignore"
753+
754+
Parameters
755+
----------
756+
values : ndarray[object]
757+
758+
Returns
759+
-------
760+
ndarray[object]
761+
"""
762+
cdef:
763+
Py_ssize_t i, n = len(values)
764+
object val
765+
766+
oresult = np.empty(n, dtype=object)
767+
768+
for i in range(n):
769+
val = values[i]
770+
771+
# set as nan except if its a NaT
772+
if checknull_with_nat(val):
773+
if isinstance(val, float):
774+
oresult[i] = np.nan
775+
else:
776+
oresult[i] = NaT
777+
elif is_datetime64_object(val):
778+
if get_datetime64_value(val) == NPY_NAT:
779+
oresult[i] = NaT
780+
else:
781+
oresult[i] = val.item()
782+
else:
783+
oresult[i] = val
784+
return oresult
785+
762786

763787
@cython.wraparound(False)
764788
@cython.boundscheck(False)

0 commit comments

Comments
 (0)