Skip to content

Commit 31ab9ce

Browse files
committed
Merge pull request #6853 from jreback/float_indexers
DEPR: Indexers will warn FutureWarning when used with a scalar indexer this is floating-point (GH4892)
2 parents ba3f6f5 + 3772f4c commit 31ab9ce

File tree

5 files changed

+97
-3
lines changed

5 files changed

+97
-3
lines changed

doc/source/release.rst

+3
Original file line numberDiff line numberDiff line change
@@ -189,6 +189,9 @@ Deprecations
189189
``FutureWarning`` is raised to alert that the old ``cols`` arguments
190190
will not be supported in a future release (:issue:`6645`)
191191

192+
- Indexers will warn ``FutureWarning`` when used with a scalar indexer and
193+
a non-floating point Index (:issue:`4892`)
194+
192195
Prior Version Deprecations/Changes
193196
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
194197

doc/source/v0.14.0.txt

+21
Original file line numberDiff line numberDiff line change
@@ -390,6 +390,27 @@ Deprecations
390390
``FutureWarning`` is raised to alert that the old ``cols`` arguments
391391
will not be supported in a future release (:issue:`6645`)
392392

393+
- Indexers will warn ``FutureWarning`` when used with a scalar indexer and
394+
a non-floating point Index (:issue:`4892`)
395+
396+
.. code-block:: python
397+
398+
# non-floating point indexes can only be indexed by integers / labels
399+
In [1]: Series(1,np.arange(5))[3.0]
400+
pandas/core/index.py:469: FutureWarning: scalar indexers for index type Int64Index should be integers and not floating point
401+
Out[1]: 1
402+
403+
In [5]: Series(1,np.arange(5)).iloc[3.0]
404+
pandas/core/index.py:469: FutureWarning: scalar indexers for index type Int64Index should be integers and not floating point
405+
Out[5]: 1
406+
407+
# these are Float64Indexes, so integer or floating point is acceptable
408+
In [3]: Series(1,np.arange(5.))[3]
409+
Out[3]: 1
410+
411+
In [4]: Series(1,np.arange(5.))[3.0]
412+
Out[4]: 1
413+
393414
.. _whatsnew_0140.enhancements:
394415

395416
Enhancements

pandas/core/index.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# pylint: disable=E1101,E1103,W0232
22
import datetime
33
from functools import partial
4+
import warnings
45
from pandas.compat import range, zip, lrange, lzip, u, reduce
56
from pandas import compat
67
import numpy as np
@@ -468,11 +469,19 @@ def to_int():
468469
return ikey
469470

470471
if typ == 'iloc':
471-
if not (is_integer(key) or is_float(key)):
472-
self._convert_indexer_error(key, 'label')
473-
return to_int()
472+
if is_integer(key):
473+
return key
474+
elif is_float(key):
475+
if not self.is_floating():
476+
warnings.warn("scalar indexers for index type {0} should be integers and not floating point".format(
477+
type(self).__name__),FutureWarning)
478+
return to_int()
479+
return self._convert_indexer_error(key, 'label')
474480

475481
if is_float(key):
482+
if not self.is_floating():
483+
warnings.warn("scalar indexers for index type {0} should be integers and not floating point".format(
484+
type(self).__name__),FutureWarning)
476485
return to_int()
477486

478487
return key

pandas/index.pyx

+2
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,8 @@ cdef class Int64Engine(IndexEngine):
355355
hash(val)
356356
if util.is_bool_object(val):
357357
raise KeyError(val)
358+
elif util.is_float_object(val):
359+
raise KeyError(val)
358360

359361
cdef _maybe_get_bool_indexer(self, object val):
360362
cdef:

pandas/tests/test_indexing.py

+59
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ class TestIndexing(tm.TestCase):
9494
_typs = set(['ints','labels','mixed','ts','floats','empty'])
9595

9696
def setUp(self):
97+
9798
import warnings
9899
warnings.filterwarnings(action='ignore', category=FutureWarning)
99100

@@ -3220,6 +3221,64 @@ def test_ix_empty_list_indexer_is_ok(self):
32203221
assert_frame_equal(df.ix[:,[]], df.iloc[:, :0]) # vertical empty
32213222
assert_frame_equal(df.ix[[],:], df.iloc[:0, :]) # horizontal empty
32223223

3224+
def test_deprecate_float_indexers(self):
3225+
3226+
# GH 4892
3227+
# deprecate allowing float indexers that are equal to ints to be used
3228+
# as indexers in non-float indices
3229+
3230+
import warnings
3231+
warnings.filterwarnings(action='error', category=FutureWarning)
3232+
3233+
for index in [ tm.makeStringIndex, tm.makeUnicodeIndex,
3234+
tm.makeDateIndex, tm.makePeriodIndex ]:
3235+
3236+
i = index(5)
3237+
s = Series(np.arange(len(i)),index=i)
3238+
self.assertRaises(FutureWarning, lambda :
3239+
s.iloc[3.0])
3240+
self.assertRaises(FutureWarning, lambda :
3241+
s[3.0])
3242+
3243+
# this is ok!
3244+
s[3]
3245+
3246+
# ints
3247+
i = index(5)
3248+
s = Series(np.arange(len(i)))
3249+
self.assertRaises(FutureWarning, lambda :
3250+
s.iloc[3.0])
3251+
3252+
# on some arch's this doesn't provide a warning (and thus raise)
3253+
# and some it does
3254+
try:
3255+
s[3.0]
3256+
except:
3257+
pass
3258+
3259+
# floats: these are all ok!
3260+
i = np.arange(5.)
3261+
s = Series(np.arange(len(i)),index=i)
3262+
with tm.assert_produces_warning(False):
3263+
s[3.0]
3264+
3265+
with tm.assert_produces_warning(False):
3266+
s[3]
3267+
3268+
with tm.assert_produces_warning(False):
3269+
s.iloc[3.0]
3270+
3271+
with tm.assert_produces_warning(False):
3272+
s.iloc[3]
3273+
3274+
with tm.assert_produces_warning(False):
3275+
s.loc[3.0]
3276+
3277+
with tm.assert_produces_warning(False):
3278+
s.loc[3]
3279+
3280+
warnings.filterwarnings(action='ignore', category=FutureWarning)
3281+
32233282
if __name__ == '__main__':
32243283
import nose
32253284
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],

0 commit comments

Comments
 (0)