Skip to content

Commit b42d1dc

Browse files
committed
BUG: introduced in #13033
closes #13052
1 parent 05e734a commit b42d1dc

File tree

3 files changed

+38
-29
lines changed

3 files changed

+38
-29
lines changed

doc/source/whatsnew/v0.18.1.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ In addition to this error change, several others have been made as well:
478478
``to_datetime`` error changes
479479
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
480480

481-
Bugs in ``pd.to_datetime()`` when passing a ``unit`` with convertible entries and ``errors='coerce'`` or non-convertible with ``errors='ignore'`` (:issue:`11758`)
481+
Bugs in ``pd.to_datetime()`` when passing a ``unit`` with convertible entries and ``errors='coerce'`` or non-convertible with ``errors='ignore'`` (:issue:`11758`, :issue:`13052`)
482482

483483
Previous behaviour:
484484

pandas/tseries/tests/test_timeseries.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -752,6 +752,16 @@ def test_to_datetime_unit(self):
752752
seconds=t) for t in range(20)] + [NaT])
753753
assert_series_equal(result, expected)
754754

755+
result = to_datetime([1, 2, 'NaT', pd.NaT, np.nan], unit='D')
756+
expected = DatetimeIndex([Timestamp('1970-01-02'),
757+
Timestamp('1970-01-03')] + ['NaT'] * 3)
758+
tm.assert_index_equal(result, expected)
759+
760+
with self.assertRaises(ValueError):
761+
to_datetime([1, 2, 'foo'], unit='D')
762+
with self.assertRaises(ValueError):
763+
to_datetime([1, 2, 111111111], unit='D')
764+
755765
def test_series_ctor_datetime64(self):
756766
rng = date_range('1/1/2000 00:00:00', '1/1/2000 1:59:50', freq='10s')
757767
dates = np.asarray(rng)

pandas/tslib.pyx

Lines changed: 27 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1992,6 +1992,7 @@ cpdef array_with_unit_to_datetime(ndarray values, unit, errors='coerce'):
19921992
ndarray[float64_t] fvalues
19931993
ndarray mask
19941994
bint is_ignore=errors=='ignore', is_coerce=errors=='coerce', is_raise=errors=='raise'
1995+
bint need_to_iterate=True
19951996
ndarray[int64_t] iresult
19961997
ndarray[object] oresult
19971998

@@ -2006,33 +2007,28 @@ cpdef array_with_unit_to_datetime(ndarray values, unit, errors='coerce'):
20062007

20072008
if is_raise:
20082009

2009-
# we can simply raise if there is a conversion
2010-
# issue; but we need to mask the nulls
2011-
# we need to guard against out-of-range conversions
2012-
# to i8
2010+
# try a quick conversion to i8
2011+
# if we have nulls that are not type-compat
2012+
# then need to iterate
20132013
try:
20142014
iresult = values.astype('i8')
20152015
mask = iresult == iNaT
20162016
iresult[mask] = 0
2017+
fvalues = iresult.astype('f8') * m
2018+
need_to_iterate=False
20172019
except:
2020+
pass
20182021

2019-
# we have nulls embedded
2020-
from pandas import isnull
2021-
2022-
values = values.astype('object')
2023-
mask = isnull(values)
2024-
values[mask] = 0
2025-
iresult = values.astype('i8')
2022+
# check the bounds
2023+
if not need_to_iterate:
20262024

2027-
fvalues = iresult.astype('f8') * m
2028-
if (fvalues < _NS_LOWER_BOUND).any() or (fvalues > _NS_UPPER_BOUND).any():
2029-
raise ValueError("cannot convert input with unit: {0}".format(unit))
2030-
result = (values*m).astype('M8[ns]')
2031-
iresult = result.view('i8')
2032-
iresult[mask] = iNaT
2033-
return result
2025+
if (fvalues < _NS_LOWER_BOUND).any() or (fvalues > _NS_UPPER_BOUND).any():
2026+
raise ValueError("cannot convert input with unit: {0}".format(unit))
2027+
result = (iresult*m).astype('M8[ns]')
2028+
iresult = result.view('i8')
2029+
iresult[mask] = iNaT
2030+
return result
20342031

2035-
# coerce or ignore
20362032
result = np.empty(n, dtype='M8[ns]')
20372033
iresult = result.view('i8')
20382034

@@ -2051,7 +2047,7 @@ cpdef array_with_unit_to_datetime(ndarray values, unit, errors='coerce'):
20512047
try:
20522048
iresult[i] = cast_from_unit(val, unit)
20532049
except:
2054-
if is_ignore:
2050+
if is_ignore or is_raise:
20552051
raise
20562052
iresult[i] = NPY_NAT
20572053

@@ -2063,24 +2059,27 @@ cpdef array_with_unit_to_datetime(ndarray values, unit, errors='coerce'):
20632059
try:
20642060
iresult[i] = cast_from_unit(float(val), unit)
20652061
except:
2066-
if is_ignore:
2062+
if is_ignore or is_raise:
20672063
raise
20682064
iresult[i] = NPY_NAT
20692065

20702066
else:
20712067

2072-
if is_ignore:
2073-
raise Exception
2068+
if is_ignore or is_raise:
2069+
raise ValueError
20742070
iresult[i] = NPY_NAT
20752071

20762072
return result
20772073

2078-
except:
2079-
pass
2074+
except (OverflowError, ValueError) as e:
2075+
2076+
# we cannot process and are done
2077+
if is_raise:
2078+
raise ValueError("cannot convert input with the unit: {0}".format(unit))
20802079

2081-
# we have hit an exception
2082-
# and are in ignore mode
2083-
# redo as object
2080+
# we have hit an exception
2081+
# and are in ignore mode
2082+
# redo as object
20842083

20852084
oresult = np.empty(n, dtype=object)
20862085
for i in range(n):

0 commit comments

Comments
 (0)