From e163de1e0c0106f2f2d42d94c51d38d5d88be276 Mon Sep 17 00:00:00 2001 From: Jean-Mathieu Deschenes Date: Thu, 13 Jul 2017 10:34:50 -0400 Subject: [PATCH 1/7] Fixes for #16896 Fixed a regression for indexing with a string with a ``TimedeltaIndex`` --- doc/source/whatsnew/v0.21.0.txt | 2 +- pandas/core/dtypes/common.py | 4 +++- pandas/tests/dtypes/test_common.py | 5 ++++- pandas/tests/indexing/test_timedelta.py | 6 ++++++ 4 files changed, 14 insertions(+), 3 deletions(-) diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index a5ee0e0ce2653..7b40e7ae04f2d 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -155,7 +155,7 @@ Indexing - When called with a null slice (e.g. ``df.iloc[:]``), the ``.iloc`` and ``.loc`` indexers return a shallow copy of the original object. Previously they returned the original object. (:issue:`13873`). - When called on an unsorted ``MultiIndex``, the ``loc`` indexer now will raise ``UnsortedIndexError`` only if proper slicing is used on non-sorted levels (:issue:`16734`). - +- Fixes regression in 0.20.3 that raises an index error when a string is used for ``TimedeltaIndex`` (:issue:`16896`). I/O ^^^ diff --git a/pandas/core/dtypes/common.py b/pandas/core/dtypes/common.py index 2eebf3704253e..ac7189d108b0a 100644 --- a/pandas/core/dtypes/common.py +++ b/pandas/core/dtypes/common.py @@ -392,13 +392,15 @@ def is_timedelta64_dtype(arr_or_dtype): False >>> is_timedelta64_dtype(pd.Series([], dtype="timedelta64[ns]")) True + >>> is_timedelta64_dtype('0 days') + False """ if arr_or_dtype is None: return False try: tipo = _get_dtype_type(arr_or_dtype) - except ValueError: + except: return False return issubclass(tipo, np.timedelta64) diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index c32e8590c5675..216238b5cd120 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -199,12 +199,15 @@ def test_is_datetime64tz_dtype(): def test_is_timedelta64_dtype(): assert not com.is_timedelta64_dtype(object) + assert not com.is_timedelta64_dtype(None) assert not com.is_timedelta64_dtype([1, 2, 3]) assert not com.is_timedelta64_dtype(np.array([], dtype=np.datetime64)) assert com.is_timedelta64_dtype(np.timedelta64) assert com.is_timedelta64_dtype(pd.Series([], dtype="timedelta64[ns]")) - + assert not com.is_timedelta64_dtype('0 days') assert not com.is_timedelta64_dtype("0 days 00:00:00") + assert not com.is_timedelta64_dtype(["0 days 00:00:00"]) + assert not com.is_timedelta64_dtype("NO DATE") def test_is_period_dtype(): diff --git a/pandas/tests/indexing/test_timedelta.py b/pandas/tests/indexing/test_timedelta.py index be3ea8f0c371d..16af6b0084359 100644 --- a/pandas/tests/indexing/test_timedelta.py +++ b/pandas/tests/indexing/test_timedelta.py @@ -40,3 +40,9 @@ def test_list_like_indexing(self, indexer, expected): dtype="int64") tm.assert_frame_equal(expected, df) + + def test_string_indexing(self): + df = pd.DataFrame({'x': range(3)}, index=pd.to_timedelta(range(3), unit='days')) + expected = df.iloc[0] + sliced = df.loc['0 days'] + tm.assert_series_equal(sliced, expected) From 2be2156a0a78179084fb92c536d6ef3c1d972737 Mon Sep 17 00:00:00 2001 From: Jean-Mathieu Deschenes Date: Thu, 13 Jul 2017 11:08:24 -0400 Subject: [PATCH 2/7] Comments from @jreback. --- doc/source/whatsnew/v0.21.0.txt | 2 +- pandas/tests/indexing/test_timedelta.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.21.0.txt b/doc/source/whatsnew/v0.21.0.txt index 7b40e7ae04f2d..0fbf865b24d50 100644 --- a/doc/source/whatsnew/v0.21.0.txt +++ b/doc/source/whatsnew/v0.21.0.txt @@ -155,7 +155,7 @@ Indexing - When called with a null slice (e.g. ``df.iloc[:]``), the ``.iloc`` and ``.loc`` indexers return a shallow copy of the original object. Previously they returned the original object. (:issue:`13873`). - When called on an unsorted ``MultiIndex``, the ``loc`` indexer now will raise ``UnsortedIndexError`` only if proper slicing is used on non-sorted levels (:issue:`16734`). -- Fixes regression in 0.20.3 that raises an index error when a string is used for ``TimedeltaIndex`` (:issue:`16896`). +- Fixes regression in 0.20.3 when indexing with a string on a ``TimedeltaIndex`` (:issue:`16896`). I/O ^^^ diff --git a/pandas/tests/indexing/test_timedelta.py b/pandas/tests/indexing/test_timedelta.py index 16af6b0084359..1e9745e712c15 100644 --- a/pandas/tests/indexing/test_timedelta.py +++ b/pandas/tests/indexing/test_timedelta.py @@ -42,6 +42,7 @@ def test_list_like_indexing(self, indexer, expected): tm.assert_frame_equal(expected, df) def test_string_indexing(self): + # GH 16896 df = pd.DataFrame({'x': range(3)}, index=pd.to_timedelta(range(3), unit='days')) expected = df.iloc[0] sliced = df.loc['0 days'] From f65c018b5ba2cb27da85bfe374bbc61856e910f3 Mon Sep 17 00:00:00 2001 From: Jean-Mathieu Deschenes Date: Thu, 13 Jul 2017 13:44:59 -0400 Subject: [PATCH 3/7] fixed linting issues --- pandas/tests/indexing/test_timedelta.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/tests/indexing/test_timedelta.py b/pandas/tests/indexing/test_timedelta.py index 1e9745e712c15..e49ec2bc613ac 100644 --- a/pandas/tests/indexing/test_timedelta.py +++ b/pandas/tests/indexing/test_timedelta.py @@ -43,7 +43,8 @@ def test_list_like_indexing(self, indexer, expected): def test_string_indexing(self): # GH 16896 - df = pd.DataFrame({'x': range(3)}, index=pd.to_timedelta(range(3), unit='days')) + df = pd.DataFrame({'x': range(3)}, + index=pd.to_timedelta(range(3), unit='days')) expected = df.iloc[0] sliced = df.loc['0 days'] tm.assert_series_equal(sliced, expected) From 21b5bd22b4720977bc86ab917f963c744508b1dd Mon Sep 17 00:00:00 2001 From: Jean-Mathieu Deschenes Date: Thu, 13 Jul 2017 14:16:18 -0400 Subject: [PATCH 4/7] Changed location of the assert The "not" are all grouped together and appear first. --- pandas/tests/dtypes/test_common.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index 216238b5cd120..14b98d87b12e8 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -202,13 +202,14 @@ def test_is_timedelta64_dtype(): assert not com.is_timedelta64_dtype(None) assert not com.is_timedelta64_dtype([1, 2, 3]) assert not com.is_timedelta64_dtype(np.array([], dtype=np.datetime64)) - assert com.is_timedelta64_dtype(np.timedelta64) - assert com.is_timedelta64_dtype(pd.Series([], dtype="timedelta64[ns]")) assert not com.is_timedelta64_dtype('0 days') assert not com.is_timedelta64_dtype("0 days 00:00:00") assert not com.is_timedelta64_dtype(["0 days 00:00:00"]) assert not com.is_timedelta64_dtype("NO DATE") + assert com.is_timedelta64_dtype(np.timedelta64) + assert com.is_timedelta64_dtype(pd.Series([], dtype="timedelta64[ns]")) + def test_is_period_dtype(): assert not com.is_period_dtype(object) From dcb274d67b4e5d44f843cee4158ebe26e4a9509f Mon Sep 17 00:00:00 2001 From: Jean-Mathieu Deschenes Date: Thu, 13 Jul 2017 14:24:19 -0400 Subject: [PATCH 5/7] Added an extra test --- pandas/tests/dtypes/test_common.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pandas/tests/dtypes/test_common.py b/pandas/tests/dtypes/test_common.py index 14b98d87b12e8..19a2deecee1f4 100644 --- a/pandas/tests/dtypes/test_common.py +++ b/pandas/tests/dtypes/test_common.py @@ -209,6 +209,7 @@ def test_is_timedelta64_dtype(): assert com.is_timedelta64_dtype(np.timedelta64) assert com.is_timedelta64_dtype(pd.Series([], dtype="timedelta64[ns]")) + assert com.is_timedelta64_dtype(pd.to_timedelta(['0 days', '1 days'])) def test_is_period_dtype(): From 7d89c1969d51c9e9c465bd272e1e5238435f2ff0 Mon Sep 17 00:00:00 2001 From: Jean-Mathieu Deschenes Date: Thu, 13 Jul 2017 15:32:25 -0400 Subject: [PATCH 6/7] Added an extra test as per @shoyer recommendation. --- pandas/tests/indexing/test_timedelta.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/tests/indexing/test_timedelta.py b/pandas/tests/indexing/test_timedelta.py index e49ec2bc613ac..1767fa288cb74 100644 --- a/pandas/tests/indexing/test_timedelta.py +++ b/pandas/tests/indexing/test_timedelta.py @@ -5,7 +5,6 @@ class TestTimedeltaIndexing(object): - def test_boolean_indexing(self): # GH 14946 df = pd.DataFrame({'x': range(10)}) @@ -48,3 +47,5 @@ def test_string_indexing(self): expected = df.iloc[0] sliced = df.loc['0 days'] tm.assert_series_equal(sliced, expected) + + assert df.index.get_loc('0 days') == 0 From 3d366951ae620c741932f056a4689e61718133ad Mon Sep 17 00:00:00 2001 From: Jean-Mathieu Deschenes Date: Thu, 13 Jul 2017 17:21:55 -0400 Subject: [PATCH 7/7] Changed assert location --- pandas/tests/indexes/timedeltas/test_timedelta.py | 3 +++ pandas/tests/indexing/test_timedelta.py | 2 -- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/pandas/tests/indexes/timedeltas/test_timedelta.py b/pandas/tests/indexes/timedeltas/test_timedelta.py index 08cf5108ffdb1..a4fc26382fb9b 100644 --- a/pandas/tests/indexes/timedeltas/test_timedelta.py +++ b/pandas/tests/indexes/timedeltas/test_timedelta.py @@ -66,6 +66,9 @@ def test_get_loc(self): for method, loc in [('pad', 1), ('backfill', 2), ('nearest', 1)]: assert idx.get_loc('1 day 1 hour', method) == loc + # GH 16896 + assert idx.get_loc('0 days') == 0 + def test_get_loc_nat(self): tidx = TimedeltaIndex(['1 days 01:00:00', 'NaT', '2 days 01:00:00']) diff --git a/pandas/tests/indexing/test_timedelta.py b/pandas/tests/indexing/test_timedelta.py index 1767fa288cb74..32609362e49af 100644 --- a/pandas/tests/indexing/test_timedelta.py +++ b/pandas/tests/indexing/test_timedelta.py @@ -47,5 +47,3 @@ def test_string_indexing(self): expected = df.iloc[0] sliced = df.loc['0 days'] tm.assert_series_equal(sliced, expected) - - assert df.index.get_loc('0 days') == 0