From 17a7fa6699955a3290abe878fb9351c5e06ddbe9 Mon Sep 17 00:00:00 2001 From: jreback Date: Fri, 24 Jan 2014 10:31:12 -0500 Subject: [PATCH] BUG: suble iloc indexing bug with single block and multi-axis indexing --- doc/source/release.rst | 1 + pandas/core/internals.py | 18 ++++++++++++++- pandas/tests/test_indexing.py | 43 +++++++++++++++++++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/doc/source/release.rst b/doc/source/release.rst index a69c0f8acaa46..d7c8a9f45999d 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -140,6 +140,7 @@ Bug Fixes - Bug in setting using fancy indexing a single element with a non-scalar (e.g. a list), (:issue:`6043`) - Regression in ``.get(None)`` indexing from 0.12 (:issue:`5652`) + - Subtle ``iloc`` indexing bug, surfaced in (:issue:`6059`) pandas 0.13.0 ------------- diff --git a/pandas/core/internals.py b/pandas/core/internals.py index dacab4fd6e6c6..ffd72b63618bd 100644 --- a/pandas/core/internals.py +++ b/pandas/core/internals.py @@ -2586,11 +2586,27 @@ def get_slice(self, slobj, axis=0, raise_on_error=False): if axis == 0: new_items = new_axes[0] + + # we want to preserver the view of a single-block if len(self.blocks) == 1: + blk = self.blocks[0] + + # see GH 6059 + ref_locs = blk._ref_locs + if ref_locs is not None: + + # need to preserve the ref_locs and just shift them + indexer = np.ones(len(ref_locs),dtype=bool) + indexer[slobj] = False + indexer = indexer.astype(int).cumsum()[slobj] + ref_locs = ref_locs[slobj] + ref_locs -= indexer + newb = make_block(blk._slice(slobj), new_items, new_items, klass=blk.__class__, fastpath=True, - placement=blk._ref_locs) + placement=ref_locs) + new_blocks = [newb] else: return self.reindex_items( diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py index b4fa32ba3160c..a8d2d497f176f 100644 --- a/pandas/tests/test_indexing.py +++ b/pandas/tests/test_indexing.py @@ -720,6 +720,49 @@ def test_iloc_getitem_frame(self): # trying to use a label self.assertRaises(ValueError, df.iloc.__getitem__, tuple(['j','D'])) + + def test_iloc_getitem_doc_issue(self): + + # multi axis slicing issue with single block + # surfaced in GH 6059 + + arr = np.random.randn(6,4) + index = date_range('20130101',periods=6) + columns = list('ABCD') + df = DataFrame(arr,index=index,columns=columns) + + # defines ref_locs + df.describe() + + result = df.iloc[3:5,0:2] + str(result) + result.dtypes + + expected = DataFrame(arr[3:5,0:2],index=index[3:5],columns=columns[0:2]) + assert_frame_equal(result,expected) + + # for dups + df.columns = list('aaaa') + result = df.iloc[3:5,0:2] + str(result) + result.dtypes + + expected = DataFrame(arr[3:5,0:2],index=index[3:5],columns=list('aa')) + assert_frame_equal(result,expected) + + # related + arr = np.random.randn(6,4) + index = list(range(0,12,2)) + columns = list(range(0,8,2)) + df = DataFrame(arr,index=index,columns=columns) + + df._data.blocks[0].ref_locs + result = df.iloc[1:5,2:4] + str(result) + result.dtypes + expected = DataFrame(arr[1:5,2:4],index=index[1:5],columns=columns[2:4]) + assert_frame_equal(result,expected) + def test_setitem_ndarray_1d(self): # GH5508