From d1bc2c1bfc72e55c81757fac315a707b968af547 Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Thu, 17 Jan 2019 18:13:19 -0800 Subject: [PATCH 1/2] use Timedelta instead of convert_to_timedelta64 --- pandas/core/tools/timedeltas.py | 10 +- .../tests/scalar/timedelta/test_timedelta.py | 121 +++++++++--------- 2 files changed, 66 insertions(+), 65 deletions(-) diff --git a/pandas/core/tools/timedeltas.py b/pandas/core/tools/timedeltas.py index 6bcf56c306e6a..e3428146b91d8 100644 --- a/pandas/core/tools/timedeltas.py +++ b/pandas/core/tools/timedeltas.py @@ -4,9 +4,7 @@ import numpy as np -from pandas._libs import tslibs -from pandas._libs.tslibs.timedeltas import ( - convert_to_timedelta64, parse_timedelta_unit) +from pandas._libs.tslibs.timedeltas import Timedelta, parse_timedelta_unit from pandas.core.dtypes.common import is_list_like from pandas.core.dtypes.generic import ABCIndexClass, ABCSeries @@ -120,7 +118,9 @@ def _coerce_scalar_to_timedelta_type(r, unit='ns', box=True, errors='raise'): """Convert string 'r' to a timedelta object.""" try: - result = convert_to_timedelta64(r, unit) + result = Timedelta(r, unit) + if not box: + result = result.asm8 except ValueError: if errors == 'raise': raise @@ -130,8 +130,6 @@ def _coerce_scalar_to_timedelta_type(r, unit='ns', box=True, errors='raise'): # coerce result = pd.NaT - if box: - result = tslibs.Timedelta(result) return result diff --git a/pandas/tests/scalar/timedelta/test_timedelta.py b/pandas/tests/scalar/timedelta/test_timedelta.py index bc753c45c803a..9b5fdfb06a9fa 100644 --- a/pandas/tests/scalar/timedelta/test_timedelta.py +++ b/pandas/tests/scalar/timedelta/test_timedelta.py @@ -10,7 +10,6 @@ import pandas as pd from pandas import ( Series, Timedelta, TimedeltaIndex, timedelta_range, to_timedelta) -from pandas.core.tools.timedeltas import _coerce_scalar_to_timedelta_type as ct import pandas.util.testing as tm @@ -373,21 +372,21 @@ def test_unit_parser(self, units, np_unit, wrapper): assert result == expected def test_numeric_conversions(self): - assert ct(0) == np.timedelta64(0, 'ns') - assert ct(10) == np.timedelta64(10, 'ns') - assert ct(10, unit='ns') == np.timedelta64(10, 'ns').astype('m8[ns]') + assert Timedelta(0) == np.timedelta64(0, 'ns') + assert Timedelta(10) == np.timedelta64(10, 'ns') + assert Timedelta(10, unit='ns') == np.timedelta64(10, 'ns') - assert ct(10, unit='us') == np.timedelta64(10, 'us').astype('m8[ns]') - assert ct(10, unit='ms') == np.timedelta64(10, 'ms').astype('m8[ns]') - assert ct(10, unit='s') == np.timedelta64(10, 's').astype('m8[ns]') - assert ct(10, unit='d') == np.timedelta64(10, 'D').astype('m8[ns]') + assert Timedelta(10, unit='us') == np.timedelta64(10, 'us') + assert Timedelta(10, unit='ms') == np.timedelta64(10, 'ms') + assert Timedelta(10, unit='s') == np.timedelta64(10, 's') + assert Timedelta(10, unit='d') == np.timedelta64(10, 'D') def test_timedelta_conversions(self): - assert (ct(timedelta(seconds=1)) == + assert (Timedelta(timedelta(seconds=1)) == np.timedelta64(1, 's').astype('m8[ns]')) - assert (ct(timedelta(microseconds=1)) == + assert (Timedelta(timedelta(microseconds=1)) == np.timedelta64(1, 'us').astype('m8[ns]')) - assert (ct(timedelta(days=1)) == + assert (Timedelta(timedelta(days=1)) == np.timedelta64(1, 'D').astype('m8[ns]')) def test_round(self): @@ -493,47 +492,49 @@ def test_short_format_converters(self): def conv(v): return v.astype('m8[ns]') - assert ct('10') == np.timedelta64(10, 'ns') - assert ct('10ns') == np.timedelta64(10, 'ns') - assert ct('100') == np.timedelta64(100, 'ns') - assert ct('100ns') == np.timedelta64(100, 'ns') - - assert ct('1000') == np.timedelta64(1000, 'ns') - assert ct('1000ns') == np.timedelta64(1000, 'ns') - assert ct('1000NS') == np.timedelta64(1000, 'ns') - - assert ct('10us') == np.timedelta64(10000, 'ns') - assert ct('100us') == np.timedelta64(100000, 'ns') - assert ct('1000us') == np.timedelta64(1000000, 'ns') - assert ct('1000Us') == np.timedelta64(1000000, 'ns') - assert ct('1000uS') == np.timedelta64(1000000, 'ns') - - assert ct('1ms') == np.timedelta64(1000000, 'ns') - assert ct('10ms') == np.timedelta64(10000000, 'ns') - assert ct('100ms') == np.timedelta64(100000000, 'ns') - assert ct('1000ms') == np.timedelta64(1000000000, 'ns') - - assert ct('-1s') == -np.timedelta64(1000000000, 'ns') - assert ct('1s') == np.timedelta64(1000000000, 'ns') - assert ct('10s') == np.timedelta64(10000000000, 'ns') - assert ct('100s') == np.timedelta64(100000000000, 'ns') - assert ct('1000s') == np.timedelta64(1000000000000, 'ns') - - assert ct('1d') == conv(np.timedelta64(1, 'D')) - assert ct('-1d') == -conv(np.timedelta64(1, 'D')) - assert ct('1D') == conv(np.timedelta64(1, 'D')) - assert ct('10D') == conv(np.timedelta64(10, 'D')) - assert ct('100D') == conv(np.timedelta64(100, 'D')) - assert ct('1000D') == conv(np.timedelta64(1000, 'D')) - assert ct('10000D') == conv(np.timedelta64(10000, 'D')) + assert Timedelta('10') == np.timedelta64(10, 'ns') + assert Timedelta('10ns') == np.timedelta64(10, 'ns') + assert Timedelta('100') == np.timedelta64(100, 'ns') + assert Timedelta('100ns') == np.timedelta64(100, 'ns') + + assert Timedelta('1000') == np.timedelta64(1000, 'ns') + assert Timedelta('1000ns') == np.timedelta64(1000, 'ns') + assert Timedelta('1000NS') == np.timedelta64(1000, 'ns') + + assert Timedelta('10us') == np.timedelta64(10000, 'ns') + assert Timedelta('100us') == np.timedelta64(100000, 'ns') + assert Timedelta('1000us') == np.timedelta64(1000000, 'ns') + assert Timedelta('1000Us') == np.timedelta64(1000000, 'ns') + assert Timedelta('1000uS') == np.timedelta64(1000000, 'ns') + + assert Timedelta('1ms') == np.timedelta64(1000000, 'ns') + assert Timedelta('10ms') == np.timedelta64(10000000, 'ns') + assert Timedelta('100ms') == np.timedelta64(100000000, 'ns') + assert Timedelta('1000ms') == np.timedelta64(1000000000, 'ns') + + assert Timedelta('-1s') == -np.timedelta64(1000000000, 'ns') + assert Timedelta('1s') == np.timedelta64(1000000000, 'ns') + assert Timedelta('10s') == np.timedelta64(10000000000, 'ns') + assert Timedelta('100s') == np.timedelta64(100000000000, 'ns') + assert Timedelta('1000s') == np.timedelta64(1000000000000, 'ns') + + assert Timedelta('1d') == conv(np.timedelta64(1, 'D')) + assert Timedelta('-1d') == -conv(np.timedelta64(1, 'D')) + assert Timedelta('1D') == conv(np.timedelta64(1, 'D')) + assert Timedelta('10D') == conv(np.timedelta64(10, 'D')) + assert Timedelta('100D') == conv(np.timedelta64(100, 'D')) + assert Timedelta('1000D') == conv(np.timedelta64(1000, 'D')) + assert Timedelta('10000D') == conv(np.timedelta64(10000, 'D')) # space - assert ct(' 10000D ') == conv(np.timedelta64(10000, 'D')) - assert ct(' - 10000D ') == -conv(np.timedelta64(10000, 'D')) + assert Timedelta(' 10000D ') == conv(np.timedelta64(10000, 'D')) + assert Timedelta(' - 10000D ') == -conv(np.timedelta64(10000, 'D')) # invalid - pytest.raises(ValueError, ct, '1foo') - pytest.raises(ValueError, ct, 'foo') + with pytest.raises(ValueError): + Timedelta('1foo') + with pytest.raises(ValueError): + Timedelta('foo') def test_full_format_converters(self): def conv(v): @@ -541,25 +542,27 @@ def conv(v): d1 = np.timedelta64(1, 'D') - assert ct('1days') == conv(d1) - assert ct('1days,') == conv(d1) - assert ct('- 1days,') == -conv(d1) + assert Timedelta('1days') == conv(d1) + assert Timedelta('1days,') == conv(d1) + assert Timedelta('- 1days,') == -conv(d1) - assert ct('00:00:01') == conv(np.timedelta64(1, 's')) - assert ct('06:00:01') == conv(np.timedelta64(6 * 3600 + 1, 's')) - assert ct('06:00:01.0') == conv(np.timedelta64(6 * 3600 + 1, 's')) - assert ct('06:00:01.01') == conv(np.timedelta64( + assert Timedelta('00:00:01') == conv(np.timedelta64(1, 's')) + assert Timedelta('06:00:01') == conv(np.timedelta64(6 * 3600 + 1, 's')) + assert Timedelta('06:00:01.0') == conv( + np.timedelta64(6 * 3600 + 1, 's')) + assert Timedelta('06:00:01.01') == conv(np.timedelta64( 1000 * (6 * 3600 + 1) + 10, 'ms')) - assert (ct('- 1days, 00:00:01') == + assert (Timedelta('- 1days, 00:00:01') == conv(-d1 + np.timedelta64(1, 's'))) - assert (ct('1days, 06:00:01') == + assert (Timedelta('1days, 06:00:01') == conv(d1 + np.timedelta64(6 * 3600 + 1, 's'))) - assert (ct('1days, 06:00:01.01') == + assert (Timedelta('1days, 06:00:01.01') == conv(d1 + np.timedelta64(1000 * (6 * 3600 + 1) + 10, 'ms'))) # invalid - pytest.raises(ValueError, ct, '- 1days, 00') + with pytest.raises(ValueError): + Timedelta('- 1days, 00') def test_overflow(self): # GH 9442 From c0e2a9e6ab50877a6c01d3240a87fb026b97d9ef Mon Sep 17 00:00:00 2001 From: Brock Mendel Date: Fri, 18 Jan 2019 07:55:15 -0800 Subject: [PATCH 2/2] change cpdef to cdef --- pandas/_libs/tslibs/timedeltas.pxd | 2 +- pandas/_libs/tslibs/timedeltas.pyx | 6 +----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/pandas/_libs/tslibs/timedeltas.pxd b/pandas/_libs/tslibs/timedeltas.pxd index c02a840281266..097309b17823b 100644 --- a/pandas/_libs/tslibs/timedeltas.pxd +++ b/pandas/_libs/tslibs/timedeltas.pxd @@ -5,4 +5,4 @@ from numpy cimport int64_t # Exposed for tslib, not intended for outside use. cdef int64_t cast_from_unit(object ts, object unit) except? -1 cpdef int64_t delta_to_nanoseconds(delta) except? -1 -cpdef convert_to_timedelta64(object ts, object unit) +cdef convert_to_timedelta64(object ts, object unit) diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index 0476ba1c78efc..0a19d8749fc7c 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -149,7 +149,7 @@ cpdef int64_t delta_to_nanoseconds(delta) except? -1: raise TypeError(type(delta)) -cpdef convert_to_timedelta64(object ts, object unit): +cdef convert_to_timedelta64(object ts, object unit): """ Convert an incoming object to a timedelta64 if possible. Before calling, unit must be standardized to avoid repeated unit conversion @@ -178,16 +178,12 @@ cpdef convert_to_timedelta64(object ts, object unit): if ts == NPY_NAT: return np.timedelta64(NPY_NAT) else: - if util.is_array(ts): - ts = ts.astype('int64').item() if unit in ['Y', 'M', 'W']: ts = np.timedelta64(ts, unit) else: ts = cast_from_unit(ts, unit) ts = np.timedelta64(ts) elif is_float_object(ts): - if util.is_array(ts): - ts = ts.astype('int64').item() if unit in ['Y', 'M', 'W']: ts = np.timedelta64(int(ts), unit) else: