From b9c3856d9cdbbfd06168e4e9da28aec3e78b252d Mon Sep 17 00:00:00 2001 From: jreback Date: Wed, 18 Jun 2014 11:24:56 -0400 Subject: [PATCH] BUG: Bug in .loc performing fallback integer indexing with object dtype indices (GH7496) --- doc/source/v0.14.1.txt | 2 ++ pandas/core/index.py | 2 +- pandas/tests/test_indexing.py | 32 ++++++++++++++++++++++++++++++++ 3 files changed, 35 insertions(+), 1 deletion(-) diff --git a/doc/source/v0.14.1.txt b/doc/source/v0.14.1.txt index 930ba13bef122..01cfa73b8b9f4 100644 --- a/doc/source/v0.14.1.txt +++ b/doc/source/v0.14.1.txt @@ -62,6 +62,8 @@ API changes when comparing a ``Period`` with another object using ``==`` if the other object isn't a ``Period`` ``False`` is returned. +- Bug in ``.loc`` performing fallback integer indexing with ``object`` dtype indices (:issue:`7496`) + .. _whatsnew_0141.prior_deprecations: Prior Version Deprecations/Changes diff --git a/pandas/core/index.py b/pandas/core/index.py index 5956cd7eea9c0..30002a719a556 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -609,7 +609,7 @@ def _convert_list_indexer_for_mixed(self, keyarr, typ=None): and we have a mixed index (e.g. number/labels). figure out the indexer. return None if we can't help """ - if com.is_integer_dtype(keyarr) and not self.is_floating(): + if (typ is None or typ in ['iloc','ix']) and (com.is_integer_dtype(keyarr) and not self.is_floating()): if self.inferred_type != 'integer': keyarr = np.where(keyarr < 0, len(self) + keyarr, keyarr) diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py index c074c4333a774..cd569deac2ceb 100644 --- a/pandas/tests/test_indexing.py +++ b/pandas/tests/test_indexing.py @@ -806,6 +806,38 @@ def test_loc_to_fail(self): # raise a KeyError? self.assertRaises(KeyError, df.loc.__getitem__, tuple([[1, 2], [1, 2]])) + # GH 7496 + # loc should not fallback + + s = Series() + s.loc[1] = 1 + s.loc['a'] = 2 + + self.assertRaises(KeyError, lambda : s.loc[-1]) + + result = s.loc[[-1, -2]] + expected = Series(np.nan,index=[-1,-2]) + assert_series_equal(result, expected) + + result = s.loc[['4']] + expected = Series(np.nan,index=['4']) + assert_series_equal(result, expected) + + s.loc[-1] = 3 + result = s.loc[[-1,-2]] + expected = Series([3,np.nan],index=[-1,-2]) + assert_series_equal(result, expected) + + s['a'] = 2 + result = s.loc[[-2]] + expected = Series([np.nan],index=[-2]) + assert_series_equal(result, expected) + + del s['a'] + def f(): + s.loc[[-2]] = 0 + self.assertRaises(KeyError, f) + def test_loc_getitem_label_slice(self): # label slices (with ints)