From eac6244c622600287185b9a389ca02efffb46130 Mon Sep 17 00:00:00 2001 From: Alexander Kirko Date: Thu, 16 Jan 2020 12:27:13 +0300 Subject: [PATCH 1/7] PERF: add Timedelta constructor shortcut --- pandas/_libs/tslibs/timedeltas.pyx | 5 ++++- pandas/tests/indexes/datetimes/test_constructors.py | 7 +++++++ 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index 0a773b8a215ed..ae56b13f66622 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -1208,7 +1208,10 @@ class Timedelta(_Timedelta): "represent unambiguous timedelta values durations." ) - if isinstance(value, Timedelta): + if (isinstance(value, Timedelta) and unit is None and + len(kwargs) == 0): + return value + elif isinstance(value, Timedelta): value = value.value elif isinstance(value, str): if len(value) > 0 and value[0] == 'P': diff --git a/pandas/tests/indexes/datetimes/test_constructors.py b/pandas/tests/indexes/datetimes/test_constructors.py index 95d14ad4c86f7..bf714ac86fc6c 100644 --- a/pandas/tests/indexes/datetimes/test_constructors.py +++ b/pandas/tests/indexes/datetimes/test_constructors.py @@ -950,3 +950,10 @@ def test_datetimeindex_constructor_misc(self): ) assert len(idx1) == len(idx2) assert idx1.freq == idx2.freq + + +def test_timedelta_constructor_identity(): + # Test for #30543 + expected = pd.Timedelta(np.timedelta64(1, 's')) + result = pd.Timedelta(expected) + assert result is expected From 8c6d2b8dd46b2a617ddde357cc663a730d1a0d4c Mon Sep 17 00:00:00 2001 From: Alexander Kirko Date: Thu, 16 Jan 2020 12:33:13 +0300 Subject: [PATCH 2/7] DOC: add comment --- pandas/_libs/tslibs/timedeltas.pyx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index ae56b13f66622..c376300454260 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -1208,6 +1208,8 @@ class Timedelta(_Timedelta): "represent unambiguous timedelta values durations." ) + # GH 30543 if pd.Timedelta already passed, return it + # check that only value is passed if (isinstance(value, Timedelta) and unit is None and len(kwargs) == 0): return value From 25b7c4624a1c7d8b286ffea86223b9caf70652ef Mon Sep 17 00:00:00 2001 From: Alexander Kirko Date: Thu, 16 Jan 2020 12:47:28 +0300 Subject: [PATCH 3/7] DOC: add to whatsnew --- doc/source/whatsnew/v1.1.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index b5a7b19f160a4..94c6ee265b5c9 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -39,7 +39,7 @@ Deprecations Performance improvements ~~~~~~~~~~~~~~~~~~~~~~~~ - +- Performance improvement in :class:`Timedelta` constructor (:issue:`30543`) - - From a9ff18fb9d13ca6c48a8c3d9069718e96e3bf192 Mon Sep 17 00:00:00 2001 From: Alexander Kirko Date: Thu, 16 Jan 2020 12:49:37 +0300 Subject: [PATCH 4/7] CLN: run black pandas --- pandas/tests/indexes/datetimes/test_constructors.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandas/tests/indexes/datetimes/test_constructors.py b/pandas/tests/indexes/datetimes/test_constructors.py index bf714ac86fc6c..b6013c3939793 100644 --- a/pandas/tests/indexes/datetimes/test_constructors.py +++ b/pandas/tests/indexes/datetimes/test_constructors.py @@ -954,6 +954,6 @@ def test_datetimeindex_constructor_misc(self): def test_timedelta_constructor_identity(): # Test for #30543 - expected = pd.Timedelta(np.timedelta64(1, 's')) + expected = pd.Timedelta(np.timedelta64(1, "s")) result = pd.Timedelta(expected) assert result is expected From 3c4af4559a75aca2e4c4ee49fd74e2b1b1bdaa0a Mon Sep 17 00:00:00 2001 From: Alexander Kirko Date: Wed, 22 Jan 2020 21:05:26 +0300 Subject: [PATCH 5/7] restart checks From 9df1fae74648c77e91c89507ca5f085d2eecc170 Mon Sep 17 00:00:00 2001 From: Alexander Kirko Date: Thu, 23 Jan 2020 11:15:31 +0300 Subject: [PATCH 6/7] TST: add benchmarks --- asv_bench/benchmarks/tslibs/timedelta.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/asv_bench/benchmarks/tslibs/timedelta.py b/asv_bench/benchmarks/tslibs/timedelta.py index 8a16ddc189483..f19f355b95a9d 100644 --- a/asv_bench/benchmarks/tslibs/timedelta.py +++ b/asv_bench/benchmarks/tslibs/timedelta.py @@ -10,6 +10,11 @@ class TimedeltaConstructor: + def setup(self): + self.nptimedelta64 = np.timedelta64(3600) + self.dttimedelta = datetime.timedelta(seconds=3600) + self.td = Timedelta(3600, unit="s") + def time_from_int(self): Timedelta(123456789) @@ -28,10 +33,10 @@ def time_from_components(self): ) def time_from_datetime_timedelta(self): - Timedelta(datetime.timedelta(days=1, seconds=1)) + Timedelta(self.dttimedelta) def time_from_np_timedelta(self): - Timedelta(np.timedelta64(1, "ms")) + Timedelta(self.nptimedelta64) def time_from_string(self): Timedelta("1 days") @@ -42,6 +47,9 @@ def time_from_iso_format(self): def time_from_missing(self): Timedelta("nat") + def time_from_pd_timedelta(self): + TimeDelta(self.td) + class TimedeltaProperties: def setup_cache(self): From 79b898fabc31ab5b4645b6a6990629c80a3d57b5 Mon Sep 17 00:00:00 2001 From: Alexander Kirko Date: Thu, 23 Jan 2020 11:39:52 +0300 Subject: [PATCH 7/7] CLN: fix typo in benchmark --- asv_bench/benchmarks/tslibs/timedelta.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/asv_bench/benchmarks/tslibs/timedelta.py b/asv_bench/benchmarks/tslibs/timedelta.py index f19f355b95a9d..6ed273281569b 100644 --- a/asv_bench/benchmarks/tslibs/timedelta.py +++ b/asv_bench/benchmarks/tslibs/timedelta.py @@ -48,7 +48,7 @@ def time_from_missing(self): Timedelta("nat") def time_from_pd_timedelta(self): - TimeDelta(self.td) + Timedelta(self.td) class TimedeltaProperties: