diff --git a/doc/source/v0.14.1.txt b/doc/source/v0.14.1.txt index c1e5877d09004..ad2e4ad44b98f 100644 --- a/doc/source/v0.14.1.txt +++ b/doc/source/v0.14.1.txt @@ -249,3 +249,5 @@ Bug Fixes - Bug in non-monotonic ``Index.union`` may preserve ``name`` incorrectly (:issue:`7458`) - Bug in ``DatetimeIndex.intersection`` doesn't preserve timezone (:issue:`4690`) +- Bug in ``Float64Index`` slicing with ``__getitem__`` (``[]``) style indexing + (:issue:`7501`). diff --git a/pandas/core/common.py b/pandas/core/common.py index 92d60ae8d8847..c29016fbe39e7 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -8,6 +8,7 @@ import codecs import csv import types +from functools import partial from datetime import datetime, timedelta from numpy.lib.format import read_array, write_array @@ -19,6 +20,7 @@ import pandas.tslib as tslib from pandas import compat from pandas.compat import StringIO, BytesIO, range, long, u, zip, map +import pandas.tools as tools from pandas.core.config import get_option from pandas.core import array as pa @@ -2290,6 +2292,18 @@ def _is_sequence(x): return False +def is_slice_of(typ_validator): + int_or_none = lambda x: x is None or typ_validator(x) + attrs = 'start', 'stop', 'step' + return lambda slc: all(map(tools.util.compose(int_or_none, + partial(getattr, slc)), + attrs)) + + +is_int_slice = is_slice_of(is_integer) + + + _ensure_float64 = algos.ensure_float64 _ensure_float32 = algos.ensure_float32 _ensure_int64 = algos.ensure_int64 diff --git a/pandas/core/index.py b/pandas/core/index.py index 5956cd7eea9c0..1de588f85c4de 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -10,6 +10,7 @@ import pandas.lib as lib import pandas.algos as _algos import pandas.index as _index +import pandas.tools as tools from pandas.lib import Timestamp, is_datetime_array from pandas.core.base import FrozenList, FrozenNDArray, IndexOpsMixin from pandas.util.decorators import cache_readonly, deprecate @@ -2004,13 +2005,10 @@ def _convert_scalar_indexer(self, key, typ=None): def _convert_slice_indexer(self, key, typ=None): """ convert a slice indexer, by definition these are labels unless we are iloc """ - if typ == 'iloc': + if typ == 'iloc' or (typ == 'getitem' and com.is_int_slice(key)): return super(Float64Index, self)._convert_slice_indexer(key, typ=typ) - - # allow floats here - validator = lambda v: v is None or is_integer(v) or is_float(v) - self._validate_slicer(key, validator) + self._validate_slicer(key, lambda v: v is None or is_float(v)) # translate to locations return self.slice_indexer(key.start, key.stop, key.step) diff --git a/pandas/tests/test_indexing.py b/pandas/tests/test_indexing.py index c074c4333a774..d2ebd17f02853 100644 --- a/pandas/tests/test_indexing.py +++ b/pandas/tests/test_indexing.py @@ -3629,6 +3629,16 @@ def test_duplicate_ix_returns_series(self): e = df.loc[0.2, 'a'] tm.assert_series_equal(r, e) + def test_float_slice_ix_style(self): + n = 5 + df = DataFrame(np.random.randn(n, 2), columns=list('ab'), + index=np.arange(0.0, n) + 50) + expected = df.iloc[2:4] + result = df[2:4] + tm.assert_frame_equal(expected, result) + + assert df[2.0:4.0].empty + if __name__ == '__main__': nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],