From ecc8d45d57a590dc604e9b14d9edb4e38d53f2a1 Mon Sep 17 00:00:00 2001 From: Michael Slater Date: Sun, 30 Jun 2019 00:24:31 +0800 Subject: [PATCH 1/9] BUG: GH26944 Fixes GH26944 AttributeError on partial multiindex timestamp slice --- doc/source/whatsnew/v0.25.0.rst | 2 +- pandas/core/indexes/multi.py | 4 +++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index a58cdc8c93ab7..fe8cd23ae2054 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -672,7 +672,7 @@ Indexing - Bug in which :meth:`DataFrame.to_csv` caused a segfault for a reindexed data frame, when the indices were single-level :class:`MultiIndex` (:issue:`26303`). - Fixed bug where assigning a :class:`arrays.PandasArray` to a :class:`pandas.core.frame.DataFrame` would raise error (:issue:`26390`) - Allow keyword arguments for callable local reference used in the :meth:`DataFrame.query` string (:issue:`26426`) - +- Bug which produced ``AttributeError`` on partial matching on a TimeStamp multiindex (:issue:`26944`) Missing ^^^^^^^ diff --git a/pandas/core/indexes/multi.py b/pandas/core/indexes/multi.py index a06d304fb5a22..074ef2934fc68 100644 --- a/pandas/core/indexes/multi.py +++ b/pandas/core/indexes/multi.py @@ -2755,7 +2755,9 @@ def convert_indexer(start, stop, step, indexer=indexer, # a partial date slicer on a DatetimeIndex generates a slice # note that the stop ALREADY includes the stopped point (if # it was a string sliced) - return convert_indexer(start.start, stop.stop, step) + start = getattr(start, 'start', start) + stop = getattr(stop, 'stop', stop) + return convert_indexer(start, stop, step) elif level > 0 or self.lexsort_depth == 0 or step is not None: # need to have like semantics here to right From c9a8f440583831d989cb2103221fad26ea377eb5 Mon Sep 17 00:00:00 2001 From: Michael Slater Date: Sun, 30 Jun 2019 09:45:52 +0800 Subject: [PATCH 2/9] BUG: GH26944 Fixes GH26944 AttributeError on partial multiindex timestamp slice and includes test. --- doc/source/whatsnew/v0.25.0.rst | 2 +- pandas/tests/indexes/multi/test_indexing.py | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index fe8cd23ae2054..7159c5267b7b6 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -672,7 +672,7 @@ Indexing - Bug in which :meth:`DataFrame.to_csv` caused a segfault for a reindexed data frame, when the indices were single-level :class:`MultiIndex` (:issue:`26303`). - Fixed bug where assigning a :class:`arrays.PandasArray` to a :class:`pandas.core.frame.DataFrame` would raise error (:issue:`26390`) - Allow keyword arguments for callable local reference used in the :meth:`DataFrame.query` string (:issue:`26426`) -- Bug which produced ``AttributeError`` on partial matching on a TimeStamp multiindex (:issue:`26944`) +- Bug which produced ``AttributeError`` on partial matching :class:`Timestamp`s in a :class:`MultiIndex` (:issue:`26944`) Missing ^^^^^^^ diff --git a/pandas/tests/indexes/multi/test_indexing.py b/pandas/tests/indexes/multi/test_indexing.py index 929c080042a45..fbf25014707c2 100644 --- a/pandas/tests/indexes/multi/test_indexing.py +++ b/pandas/tests/indexes/multi/test_indexing.py @@ -397,3 +397,12 @@ def test_get_indexer_categorical_time(): Categorical(date_range("2012-01-01", periods=3, freq='H'))]) result = midx.get_indexer(midx) tm.assert_numpy_array_equal(result, np.arange(9, dtype=np.intp)) + + +def test_timestamp_multiindex_indexer(): + # https://github.com/pandas-dev/pandas/issues/26944 + dt_index = pd.date_range(start="1jan2019 00:15:33", periods=100, freq="h", name="date") + df = pd.DataFrame(index=dt_index, data={'foo': range(len(dt_index)), 'bar': 'x', 'zaa': 3}) + df = df.reset_index().set_index(["date", "bar", "zaa"]) + assert df.loc[pd.IndexSlice['2019-1-2':, "x", :], 'foo'][-1] == 98 + From a41b49d551cd1da2452d1a471faa0d0dbf22fdab Mon Sep 17 00:00:00 2001 From: Michael Slater Date: Sun, 30 Jun 2019 09:50:33 +0800 Subject: [PATCH 3/9] BUG: GH26944 Fixes GH26944 AttributeError on partial multiindex timestamp slice and includes test and PEP8 correction. --- pandas/tests/indexes/multi/test_indexing.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/pandas/tests/indexes/multi/test_indexing.py b/pandas/tests/indexes/multi/test_indexing.py index fbf25014707c2..bbaa6c8826d0a 100644 --- a/pandas/tests/indexes/multi/test_indexing.py +++ b/pandas/tests/indexes/multi/test_indexing.py @@ -401,8 +401,9 @@ def test_get_indexer_categorical_time(): def test_timestamp_multiindex_indexer(): # https://github.com/pandas-dev/pandas/issues/26944 - dt_index = pd.date_range(start="1jan2019 00:15:33", periods=100, freq="h", name="date") - df = pd.DataFrame(index=dt_index, data={'foo': range(len(dt_index)), 'bar': 'x', 'zaa': 3}) + dt_index = pd.date_range(start="1jan2019 00:15:33", periods=100, + freq="h", name="date") + df = pd.DataFrame(index=dt_index, + data={'foo': range(len(dt_index)), 'bar': 'x', 'zaa': 3}) df = df.reset_index().set_index(["date", "bar", "zaa"]) - assert df.loc[pd.IndexSlice['2019-1-2':, "x", :], 'foo'][-1] == 98 - + assert df.loc[pd.IndexSlice['2019-1-2':, "x", :], 'foo'][-1] == 98 \ No newline at end of file From cc61ba6c8921fcc0e95dd4c6c7ab02fbc6c8cfcb Mon Sep 17 00:00:00 2001 From: Michael Slater Date: Sun, 30 Jun 2019 10:22:43 +0800 Subject: [PATCH 4/9] BUG: GH26944 Fixes GH26944 AttributeError on partial multiindex timestamp slice and includes test and PEP8 corrections. --- pandas/tests/indexes/multi/test_indexing.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/tests/indexes/multi/test_indexing.py b/pandas/tests/indexes/multi/test_indexing.py index bbaa6c8826d0a..36354e2e4a7be 100644 --- a/pandas/tests/indexes/multi/test_indexing.py +++ b/pandas/tests/indexes/multi/test_indexing.py @@ -406,4 +406,5 @@ def test_timestamp_multiindex_indexer(): df = pd.DataFrame(index=dt_index, data={'foo': range(len(dt_index)), 'bar': 'x', 'zaa': 3}) df = df.reset_index().set_index(["date", "bar", "zaa"]) - assert df.loc[pd.IndexSlice['2019-1-2':, "x", :], 'foo'][-1] == 98 \ No newline at end of file + assert df.loc[pd.IndexSlice['2019-1-2':, "x", :], 'foo'][-1] == 98 + \ No newline at end of file From 35f5e42aff28faacecb51f411c1524af477b6389 Mon Sep 17 00:00:00 2001 From: Michael Slater Date: Sun, 30 Jun 2019 10:36:12 +0800 Subject: [PATCH 5/9] BUG: GH26944 Fixes GH26944 AttributeError on partial multiindex timestamp slice and includes test and PEP8 corrections w293, w391. --- pandas/tests/indexes/multi/test_indexing.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pandas/tests/indexes/multi/test_indexing.py b/pandas/tests/indexes/multi/test_indexing.py index 36354e2e4a7be..fcf257e843bd5 100644 --- a/pandas/tests/indexes/multi/test_indexing.py +++ b/pandas/tests/indexes/multi/test_indexing.py @@ -407,4 +407,3 @@ def test_timestamp_multiindex_indexer(): data={'foo': range(len(dt_index)), 'bar': 'x', 'zaa': 3}) df = df.reset_index().set_index(["date", "bar", "zaa"]) assert df.loc[pd.IndexSlice['2019-1-2':, "x", :], 'foo'][-1] == 98 - \ No newline at end of file From 3da19fff41f52d9f93e3dcc5caad4c1a507992be Mon Sep 17 00:00:00 2001 From: Michael Slater Date: Sun, 30 Jun 2019 11:44:54 +0800 Subject: [PATCH 6/9] BUG: GH26944 Fixes GH26944 AttributeError on partial multiindex timestamp slice and includes test and PEP8 corrections w293, w391. Simplified test code. --- doc/source/whatsnew/v0.25.0.rst | 2 +- pandas/tests/indexes/multi/test_indexing.py | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/doc/source/whatsnew/v0.25.0.rst b/doc/source/whatsnew/v0.25.0.rst index 7159c5267b7b6..d43ace99a55f6 100644 --- a/doc/source/whatsnew/v0.25.0.rst +++ b/doc/source/whatsnew/v0.25.0.rst @@ -672,7 +672,7 @@ Indexing - Bug in which :meth:`DataFrame.to_csv` caused a segfault for a reindexed data frame, when the indices were single-level :class:`MultiIndex` (:issue:`26303`). - Fixed bug where assigning a :class:`arrays.PandasArray` to a :class:`pandas.core.frame.DataFrame` would raise error (:issue:`26390`) - Allow keyword arguments for callable local reference used in the :meth:`DataFrame.query` string (:issue:`26426`) -- Bug which produced ``AttributeError`` on partial matching :class:`Timestamp`s in a :class:`MultiIndex` (:issue:`26944`) +- Bug which produced ``AttributeError`` on partial matching :class:`Timestamp` in a :class:`MultiIndex` (:issue:`26944`) Missing ^^^^^^^ diff --git a/pandas/tests/indexes/multi/test_indexing.py b/pandas/tests/indexes/multi/test_indexing.py index fcf257e843bd5..29e0049f7ea93 100644 --- a/pandas/tests/indexes/multi/test_indexing.py +++ b/pandas/tests/indexes/multi/test_indexing.py @@ -401,9 +401,10 @@ def test_get_indexer_categorical_time(): def test_timestamp_multiindex_indexer(): # https://github.com/pandas-dev/pandas/issues/26944 - dt_index = pd.date_range(start="1jan2019 00:15:33", periods=100, - freq="h", name="date") - df = pd.DataFrame(index=dt_index, - data={'foo': range(len(dt_index)), 'bar': 'x', 'zaa': 3}) - df = df.reset_index().set_index(["date", "bar", "zaa"]) + idx = pd.MultiIndex.from_product([ + pd.date_range("2019-01-01T00:15:33", periods=100, freq="H", name="date"), + ['x'], + [3] + ]) + df = pd.DataFrame({'foo': np.arange(len(idx))}, idx) assert df.loc[pd.IndexSlice['2019-1-2':, "x", :], 'foo'][-1] == 98 From df5fdb0e6f2ead45dea7d0e3da6dc870f06e56fe Mon Sep 17 00:00:00 2001 From: Michael Slater Date: Sun, 30 Jun 2019 11:48:33 +0800 Subject: [PATCH 7/9] BUG: GH26944 Fixes GH26944 AttributeError on partial multiindex timestamp slice and includes test and PEP8 corrections w293, w391. Simplified test code. E501 --- pandas/tests/indexes/multi/test_indexing.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/tests/indexes/multi/test_indexing.py b/pandas/tests/indexes/multi/test_indexing.py index 29e0049f7ea93..0c878f723421a 100644 --- a/pandas/tests/indexes/multi/test_indexing.py +++ b/pandas/tests/indexes/multi/test_indexing.py @@ -402,7 +402,8 @@ def test_get_indexer_categorical_time(): def test_timestamp_multiindex_indexer(): # https://github.com/pandas-dev/pandas/issues/26944 idx = pd.MultiIndex.from_product([ - pd.date_range("2019-01-01T00:15:33", periods=100, freq="H", name="date"), + pd.date_range("2019-01-01T00:15:33", periods=100, freq="H", + name="date"), ['x'], [3] ]) From 7458cd82e63f46877ba296658e0e18061334c29b Mon Sep 17 00:00:00 2001 From: Michael Slater Date: Mon, 1 Jul 2019 23:36:48 +0800 Subject: [PATCH 8/9] BUG: GH26944 Fixes GH26944 AttributeError on partial multiindex timestamp slice and includes test and PEP8 corrections w293, w391. Simplified test code. E501. changed assertion method. --- pandas/tests/indexes/multi/test_indexing.py | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/pandas/tests/indexes/multi/test_indexing.py b/pandas/tests/indexes/multi/test_indexing.py index 0c878f723421a..4c6e555d82282 100644 --- a/pandas/tests/indexes/multi/test_indexing.py +++ b/pandas/tests/indexes/multi/test_indexing.py @@ -404,8 +404,17 @@ def test_timestamp_multiindex_indexer(): idx = pd.MultiIndex.from_product([ pd.date_range("2019-01-01T00:15:33", periods=100, freq="H", name="date"), - ['x'], - [3] - ]) + ['x'], + [3] + ]) df = pd.DataFrame({'foo': np.arange(len(idx))}, idx) - assert df.loc[pd.IndexSlice['2019-1-2':, "x", :], 'foo'][-1] == 98 + result = df.loc[pd.IndexSlice['2019-1-2':, "x", :], 'foo'] + qidx = pd.MultiIndex.from_product([ + pd.date_range(start="2019-01-02T00:15:33", end='2019-01-05T02:15:33', + freq="H", name="date"), + ['x'], + [3] + ]) + should_be = pd.Series(data=np.arange(24,len(qidx)+24), index=qidx, + name="foo") + tm.assert_series_equal(result, should_be) From f8dfd84e6dc3dbe67bb5ed3f8b388039c0954de6 Mon Sep 17 00:00:00 2001 From: Michael Slater Date: Mon, 1 Jul 2019 23:41:51 +0800 Subject: [PATCH 9/9] BUG: GH26944 Fixes GH26944 AttributeError on partial multiindex timestamp slice and includes test and PEP8 corrections w293, w391. Simplified test code. E501. changed assertion method. more pep8 violations. --- pandas/tests/indexes/multi/test_indexing.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/pandas/tests/indexes/multi/test_indexing.py b/pandas/tests/indexes/multi/test_indexing.py index 4c6e555d82282..3acd194b28a05 100644 --- a/pandas/tests/indexes/multi/test_indexing.py +++ b/pandas/tests/indexes/multi/test_indexing.py @@ -404,17 +404,17 @@ def test_timestamp_multiindex_indexer(): idx = pd.MultiIndex.from_product([ pd.date_range("2019-01-01T00:15:33", periods=100, freq="H", name="date"), - ['x'], - [3] - ]) + ['x'], + [3] + ]) df = pd.DataFrame({'foo': np.arange(len(idx))}, idx) result = df.loc[pd.IndexSlice['2019-1-2':, "x", :], 'foo'] qidx = pd.MultiIndex.from_product([ pd.date_range(start="2019-01-02T00:15:33", end='2019-01-05T02:15:33', - freq="H", name="date"), - ['x'], - [3] - ]) - should_be = pd.Series(data=np.arange(24,len(qidx)+24), index=qidx, + freq="H", name="date"), + ['x'], + [3] + ]) + should_be = pd.Series(data=np.arange(24, len(qidx) + 24), index=qidx, name="foo") tm.assert_series_equal(result, should_be)