From 99c6b6d71808b9a9ef55bef74cf7f436c660f891 Mon Sep 17 00:00:00 2001 From: Eric Goddard Date: Wed, 5 Aug 2020 16:35:33 -0500 Subject: [PATCH 1/4] BUG: to_timedelta fails on Int64 Series with null values --- pandas/core/arrays/timedeltas.py | 4 +++- pandas/tests/tools/test_to_timedelta.py | 12 ++++++++++++ 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index a378423df788b..4178e1a5b2eec 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -29,7 +29,7 @@ from pandas.core import nanops from pandas.core.algorithms import checked_add_with_arr -from pandas.core.arrays import datetimelike as dtl +from pandas.core.arrays import datetimelike as dtl, IntegerArray from pandas.core.arrays._ranges import generate_regular_range import pandas.core.common as com from pandas.core.construction import extract_array @@ -921,6 +921,8 @@ def sequence_to_td64ns(data, copy=False, unit=None, errors="raise"): elif isinstance(data, (ABCTimedeltaIndex, TimedeltaArray)): inferred_freq = data.freq data = data._data + elif isinstance(data, IntegerArray): + data = data.to_numpy("int64", na_value=tslibs.iNaT) # Convert whatever we have into timedelta64[ns] dtype if is_object_dtype(data.dtype) or is_string_dtype(data.dtype): diff --git a/pandas/tests/tools/test_to_timedelta.py b/pandas/tests/tools/test_to_timedelta.py index 1e193f22a6698..3bc4a3dd83d13 100644 --- a/pandas/tests/tools/test_to_timedelta.py +++ b/pandas/tests/tools/test_to_timedelta.py @@ -24,6 +24,18 @@ def test_to_timedelta(self): result = to_timedelta(Series(["1d", "1days 00:00:01"])) tm.assert_series_equal(result, expected) + # IntegerArray Series + expected = Series([timedelta(days=1), timedelta(days=2)]) + result = to_timedelta(Series([1, 2], dtype="Int64"), unit="days") + + tm.assert_series_equal(result, expected) + + # IntegerArray Series with nulls + expected = Series([timedelta(days=1), None]) + result = to_timedelta(Series([1, None], dtype="Int64"), unit="days") + + tm.assert_series_equal(result, expected) + # with units result = TimedeltaIndex( [np.timedelta64(0, "ns"), np.timedelta64(10, "s").astype("m8[ns]")] From 4fbe7296477fd4b3098a05fb7b35fcc0f14d36bd Mon Sep 17 00:00:00 2001 From: Eric Goddard Date: Thu, 6 Aug 2020 06:46:49 -0500 Subject: [PATCH 2/4] Move nullable int64 dtypes to separate test and isort --- pandas/core/arrays/timedeltas.py | 2 +- pandas/tests/tools/test_to_timedelta.py | 24 ++++++++++++------------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index 4178e1a5b2eec..a30e1060c64f1 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -29,7 +29,7 @@ from pandas.core import nanops from pandas.core.algorithms import checked_add_with_arr -from pandas.core.arrays import datetimelike as dtl, IntegerArray +from pandas.core.arrays import IntegerArray, datetimelike as dtl from pandas.core.arrays._ranges import generate_regular_range import pandas.core.common as com from pandas.core.construction import extract_array diff --git a/pandas/tests/tools/test_to_timedelta.py b/pandas/tests/tools/test_to_timedelta.py index 3bc4a3dd83d13..674b6a4bfd7d9 100644 --- a/pandas/tests/tools/test_to_timedelta.py +++ b/pandas/tests/tools/test_to_timedelta.py @@ -24,18 +24,6 @@ def test_to_timedelta(self): result = to_timedelta(Series(["1d", "1days 00:00:01"])) tm.assert_series_equal(result, expected) - # IntegerArray Series - expected = Series([timedelta(days=1), timedelta(days=2)]) - result = to_timedelta(Series([1, 2], dtype="Int64"), unit="days") - - tm.assert_series_equal(result, expected) - - # IntegerArray Series with nulls - expected = Series([timedelta(days=1), None]) - result = to_timedelta(Series([1, None], dtype="Int64"), unit="days") - - tm.assert_series_equal(result, expected) - # with units result = TimedeltaIndex( [np.timedelta64(0, "ns"), np.timedelta64(10, "s").astype("m8[ns]")] @@ -178,3 +166,15 @@ def test_to_timedelta_ignore_strings_unit(self): arr = np.array([1, 2, "error"], dtype=object) result = pd.to_timedelta(arr, unit="ns", errors="ignore") tm.assert_numpy_array_equal(result, arr) + + def test_to_timedelta_nullable_int64_dtype(self): + expected = Series([timedelta(days=1), timedelta(days=2)]) + result = to_timedelta(Series([1, 2], dtype="Int64"), unit="days") + + tm.assert_series_equal(result, expected) + + # IntegerArray Series with nulls + expected = Series([timedelta(days=1), None]) + result = to_timedelta(Series([1, None], dtype="Int64"), unit="days") + + tm.assert_series_equal(result, expected) From 77389bb1ce8b45fc22a458ada2b77dd6c98db607 Mon Sep 17 00:00:00 2001 From: Eric Goddard Date: Thu, 6 Aug 2020 07:27:42 -0500 Subject: [PATCH 3/4] Update whatsnew v1.1.1.rst --- doc/source/whatsnew/v1.1.1.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/doc/source/whatsnew/v1.1.1.rst b/doc/source/whatsnew/v1.1.1.rst index 6a327a4fc732f..e9bac816b5abc 100644 --- a/doc/source/whatsnew/v1.1.1.rst +++ b/doc/source/whatsnew/v1.1.1.rst @@ -38,6 +38,11 @@ Categorical - - +**Timedelta** + +- Bug in :meth:`to_timedelta` fails when arg is a :class:`Series` with `Int64` dtype containing null values (:issue:`35574`) + + **Numeric** - From 1ace0ecfd3e4e11eb6feed51e0ec57c5fc858ca9 Mon Sep 17 00:00:00 2001 From: Eric Goddard Date: Thu, 6 Aug 2020 20:22:54 -0500 Subject: [PATCH 4/4] Add GH issue number to tests --- pandas/tests/tools/test_to_timedelta.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/tools/test_to_timedelta.py b/pandas/tests/tools/test_to_timedelta.py index 674b6a4bfd7d9..f68d83f7f4d58 100644 --- a/pandas/tests/tools/test_to_timedelta.py +++ b/pandas/tests/tools/test_to_timedelta.py @@ -168,6 +168,7 @@ def test_to_timedelta_ignore_strings_unit(self): tm.assert_numpy_array_equal(result, arr) def test_to_timedelta_nullable_int64_dtype(self): + # GH 35574 expected = Series([timedelta(days=1), timedelta(days=2)]) result = to_timedelta(Series([1, 2], dtype="Int64"), unit="days")