From b3b51400e27b87b99322cb6642897b9e5ecb4ab0 Mon Sep 17 00:00:00 2001 From: Wes McKinney Date: Mon, 23 Jan 2012 21:26:52 -0500 Subject: [PATCH] BUG: fix integer-slicing from integers-as-floats, GH #670 --- pandas/core/indexing.py | 15 +++++++++------ pandas/tests/test_series.py | 11 +++++++++++ 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index db474fa84ad80..e7a1d2e4c7d79 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -220,7 +220,7 @@ def _convert_to_indexer(self, obj, axis=0): is_int_index = _is_integer_index(labels) if isinstance(obj, slice): - int_slice = _is_integer_slice(obj) + int_slice = _is_index_slice(obj) null_slice = obj.start is None and obj.stop is None # could have integers in the first level of the MultiIndex position_slice = (int_slice @@ -234,7 +234,7 @@ def _convert_to_indexer(self, obj, axis=0): i, j = labels.slice_locs(obj.start, obj.stop) slicer = slice(i, j, obj.step) except Exception: - if _is_integer_slice(obj): + if _is_index_slice(obj): if labels.inferred_type == 'integer': raise slicer = obj @@ -276,7 +276,7 @@ def _get_slice_axis(self, slice_obj, axis=0): axis_name = obj._get_axis_name(axis) labels = getattr(obj, axis_name) - int_slice = _is_integer_slice(slice_obj) + int_slice = _is_index_slice(slice_obj) null_slice = slice_obj.start is None and slice_obj.stop is None # could have integers in the first level of the MultiIndex @@ -289,7 +289,7 @@ def _get_slice_axis(self, slice_obj, axis=0): i, j = labels.slice_locs(slice_obj.start, slice_obj.stop) slicer = slice(i, j, slice_obj.step) except Exception: - if _is_integer_slice(slice_obj): + if _is_index_slice(slice_obj): if labels.inferred_type == 'integer': raise slicer = slice_obj @@ -301,9 +301,12 @@ def _get_slice_axis(self, slice_obj, axis=0): return self._slice(slicer, axis=axis) -def _is_integer_slice(obj): +def _is_index_slice(obj): + def _is_valid_index(x): + return com.is_integer(x) or com.is_float(x) and np.allclose(x, int(x)) + def _crit(v): - return v is None or com.is_integer(v) + return v is None or _is_valid_index(v) both_none = obj.start is None and obj.stop is None diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py index aba50e42db3e2..ecc51053ed756 100644 --- a/pandas/tests/test_series.py +++ b/pandas/tests/test_series.py @@ -483,6 +483,17 @@ def test_slice_can_reorder_not_uniquely_indexed(self): s = Series(1, index=['a', 'a', 'b', 'b', 'c']) result = s[::-1] # it works! + def test_slice_float_get_set(self): + result = self.ts[4.0:10.0] + expected = self.ts[4:10] + assert_series_equal(result, expected) + + self.ts[4.0:10.0] = 0 + self.assert_((self.ts[4:10] == 0).all()) + + self.assertRaises(TypeError, self.ts.__getitem__, slice(4.5, 10.0)) + self.assertRaises(TypeError, self.ts.__setitem__, slice(4.5, 10.0), 0) + def test_setitem(self): self.ts[self.ts.index[5]] = np.NaN self.ts[[1,2,17]] = np.NaN