Skip to content

Commit 4ac34d6

Browse files
BeforeFlightquintusdias
authored andcommitted
BUG: maybe_convert_objects mixed datetimes and timedeltas (pandas-dev#27438)
1 parent 297f43b commit 4ac34d6

File tree

2 files changed

+46
-6
lines changed

2 files changed

+46
-6
lines changed

pandas/_libs/lib.pyx

+27-6
Original file line numberDiff line numberDiff line change
@@ -953,6 +953,7 @@ cdef class Seen:
953953

954954
cdef:
955955
bint int_ # seen_int
956+
bint nat_ # seen nat
956957
bint bool_ # seen_bool
957958
bint null_ # seen_null
958959
bint uint_ # seen_uint (unsigned integer)
@@ -976,6 +977,7 @@ cdef class Seen:
976977
initial methods to convert to numeric fail.
977978
"""
978979
self.int_ = 0
980+
self.nat_ = 0
979981
self.bool_ = 0
980982
self.null_ = 0
981983
self.uint_ = 0
@@ -1055,11 +1057,13 @@ cdef class Seen:
10551057

10561058
@property
10571059
def is_bool(self):
1058-
return not (self.datetime_ or self.numeric_ or self.timedelta_)
1060+
return not (self.datetime_ or self.numeric_ or self.timedelta_
1061+
or self.nat_)
10591062

10601063
@property
10611064
def is_float_or_complex(self):
1062-
return not (self.bool_ or self.datetime_ or self.timedelta_)
1065+
return not (self.bool_ or self.datetime_ or self.timedelta_
1066+
or self.nat_)
10631067

10641068

10651069
cdef _try_infer_map(v):
@@ -1958,12 +1962,11 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0,
19581962
seen.null_ = 1
19591963
floats[i] = complexes[i] = fnan
19601964
elif val is NaT:
1965+
seen.nat_ = 1
19611966
if convert_datetime:
19621967
idatetimes[i] = NPY_NAT
1963-
seen.datetime_ = 1
19641968
if convert_timedelta:
19651969
itimedeltas[i] = NPY_NAT
1966-
seen.timedelta_ = 1
19671970
if not (convert_datetime or convert_timedelta):
19681971
seen.object_ = 1
19691972
break
@@ -2057,11 +2060,20 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0,
20572060
else:
20582061
if not seen.bool_:
20592062
if seen.datetime_:
2060-
if not seen.numeric_:
2063+
if not seen.numeric_ and not seen.timedelta_:
20612064
return datetimes
20622065
elif seen.timedelta_:
20632066
if not seen.numeric_:
20642067
return timedeltas
2068+
elif seen.nat_:
2069+
if not seen.numeric_:
2070+
if convert_datetime and convert_timedelta:
2071+
# TODO: array full of NaT ambiguity resolve here needed
2072+
pass
2073+
elif convert_datetime:
2074+
return datetimes
2075+
elif convert_timedelta:
2076+
return timedeltas
20652077
else:
20662078
if seen.complex_:
20672079
return complexes
@@ -2088,11 +2100,20 @@ def maybe_convert_objects(ndarray[object] objects, bint try_float=0,
20882100
else:
20892101
if not seen.bool_:
20902102
if seen.datetime_:
2091-
if not seen.numeric_:
2103+
if not seen.numeric_ and not seen.timedelta_:
20922104
return datetimes
20932105
elif seen.timedelta_:
20942106
if not seen.numeric_:
20952107
return timedeltas
2108+
elif seen.nat_:
2109+
if not seen.numeric_:
2110+
if convert_datetime and convert_timedelta:
2111+
# TODO: array full of NaT ambiguity resolve here needed
2112+
pass
2113+
elif convert_datetime:
2114+
return datetimes
2115+
elif convert_timedelta:
2116+
return timedeltas
20962117
else:
20972118
if seen.complex_:
20982119
if not seen.int_:

pandas/tests/dtypes/test_inference.py

+19
Original file line numberDiff line numberDiff line change
@@ -531,6 +531,25 @@ def test_maybe_convert_objects_uint64(self):
531531
exp = np.array([2 ** 63, -1], dtype=object)
532532
tm.assert_numpy_array_equal(lib.maybe_convert_objects(arr), exp)
533533

534+
def test_maybe_convert_objects_datetime(self):
535+
# GH27438
536+
arr = np.array(
537+
[np.datetime64("2000-01-01"), np.timedelta64(1, "s")], dtype=object
538+
)
539+
exp = arr.copy()
540+
out = lib.maybe_convert_objects(arr, convert_datetime=1, convert_timedelta=1)
541+
tm.assert_numpy_array_equal(out, exp)
542+
543+
arr = np.array([pd.NaT, np.timedelta64(1, "s")], dtype=object)
544+
exp = np.array([np.timedelta64("NaT"), np.timedelta64(1, "s")], dtype="m8[ns]")
545+
out = lib.maybe_convert_objects(arr, convert_datetime=1, convert_timedelta=1)
546+
tm.assert_numpy_array_equal(out, exp)
547+
548+
arr = np.array([np.timedelta64(1, "s"), np.nan], dtype=object)
549+
exp = arr.copy()
550+
out = lib.maybe_convert_objects(arr, convert_datetime=1, convert_timedelta=1)
551+
tm.assert_numpy_array_equal(out, exp)
552+
534553
def test_mixed_dtypes_remain_object_array(self):
535554
# GH14956
536555
array = np.array([datetime(2015, 1, 1, tzinfo=pytz.utc), 1], dtype=object)

0 commit comments

Comments
 (0)