From 388ec4950c986b68118752ae9f6bc24c9e8b8205 Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 15 Oct 2020 15:27:28 -0700 Subject: [PATCH 1/2] BUG: DataFrame.__getitem__(number) with IntervalIndex columns #26490 --- doc/source/whatsnew/v1.2.0.rst | 1 + pandas/core/frame.py | 2 +- pandas/tests/frame/indexing/test_indexing.py | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 9fc094330fb36..1788b6f7f7fb8 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -400,6 +400,7 @@ Indexing - Bug in :meth:`DataFrame.sort_index` where parameter ascending passed as a list on a single level index gives wrong result. (:issue:`32334`) - Bug in :meth:`DataFrame.reset_index` was incorrectly raising a ``ValueError`` for input with a :class:`MultiIndex` with missing values in a level with ``Categorical`` dtype (:issue:`24206`) - Bug in indexing with boolean masks on datetime-like values sometimes returning a view instead of a copy (:issue:`36210`) +- Bug in :meth:`DataFrame.__getitem__` and :meth:`DataFrame.loc.__getitem__` with :class:`IntervalIndex` columns and a numeric indexer (:issue:`26490`) Missing ^^^^^^^ diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 539275c7ff617..75d2754635f88 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -2946,7 +2946,7 @@ def __getitem__(self, key): # - the key itself is repeated (test on data.shape, #9519), or # - we have a MultiIndex on columns (test on self.columns, #21309) if data.shape[1] == 1 and not isinstance(self.columns, MultiIndex): - data = data[key] + data = data._ixs(0, axis=1) return data diff --git a/pandas/tests/frame/indexing/test_indexing.py b/pandas/tests/frame/indexing/test_indexing.py index 507d01f5b900c..c097557b33f4e 100644 --- a/pandas/tests/frame/indexing/test_indexing.py +++ b/pandas/tests/frame/indexing/test_indexing.py @@ -2160,6 +2160,20 @@ def test_interval_index(self): result = df.loc[1, "A"] tm.assert_series_equal(result, expected) + def test_getitem_interval_index_partial_indexing(self): + # GH#36490 + df = pd.DataFrame( + np.ones((3, 4)), columns=pd.IntervalIndex.from_breaks(np.arange(5)) + ) + + expected = df.iloc[:, 0] + + res = df[0.5] + tm.assert_series_equal(res, expected) + + res = df.loc[:, 0.5] + tm.assert_series_equal(res, expected) + class TestDataFrameIndexingUInt64: def test_setitem(self, uint64_frame): From 42add9f916dc5e1e56f5401fbd2340b92ddf0452 Mon Sep 17 00:00:00 2001 From: Brock Date: Thu, 15 Oct 2020 15:41:19 -0700 Subject: [PATCH 2/2] BUG: series.loc[[]] with non-unique MultiInex #13691 --- doc/source/whatsnew/v1.2.0.rst | 1 + pandas/core/indexes/base.py | 4 ++++ pandas/tests/series/indexing/test_multiindex.py | 14 ++++++++++++++ 3 files changed, 19 insertions(+) diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 1788b6f7f7fb8..6bd3c5345d06a 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -401,6 +401,7 @@ Indexing - Bug in :meth:`DataFrame.reset_index` was incorrectly raising a ``ValueError`` for input with a :class:`MultiIndex` with missing values in a level with ``Categorical`` dtype (:issue:`24206`) - Bug in indexing with boolean masks on datetime-like values sometimes returning a view instead of a copy (:issue:`36210`) - Bug in :meth:`DataFrame.__getitem__` and :meth:`DataFrame.loc.__getitem__` with :class:`IntervalIndex` columns and a numeric indexer (:issue:`26490`) +- Bug in :meth:`Series.loc.__getitem__` with a non-unique :class:`MultiIndex` and an empty-list indexer (:issue:`13691`) Missing ^^^^^^^ diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index 6b71e455782e3..87dd15d5b142b 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -3404,6 +3404,10 @@ def _reindex_non_unique(self, target): """ target = ensure_index(target) + if len(target) == 0: + # GH#13691 + return self[:0], np.array([], dtype=np.intp), None + indexer, missing = self.get_indexer_non_unique(target) check = indexer != -1 new_labels = self.take(indexer[check]) diff --git a/pandas/tests/series/indexing/test_multiindex.py b/pandas/tests/series/indexing/test_multiindex.py index 0420d76b5e8a8..ed8bc52db7a9e 100644 --- a/pandas/tests/series/indexing/test_multiindex.py +++ b/pandas/tests/series/indexing/test_multiindex.py @@ -49,3 +49,17 @@ def test_nat_multi_index(ix_data, exp_data): expected = pd.DataFrame(exp_data) tm.assert_frame_equal(result, expected) + + +def test_loc_getitem_multiindex_nonunique_len_zero(): + # GH#13691 + mi = pd.MultiIndex.from_product([[0], [1, 1]]) + ser = pd.Series(0, index=mi) + + res = ser.loc[[]] + + expected = ser[:0] + tm.assert_series_equal(res, expected) + + res2 = ser.loc[ser.iloc[0:0]] + tm.assert_series_equal(res2, expected)