Skip to content

BUG: Check types in Index.__contains__ (#22085) #22602

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Sep 19, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.24.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -723,6 +723,7 @@ Indexing
- ``Float64Index.get_loc`` now raises ``KeyError`` when boolean key passed. (:issue:`19087`)
- Bug in :meth:`DataFrame.loc` when indexing with an :class:`IntervalIndex` (:issue:`19977`)
- :class:`Index` no longer mangles ``None``, ``NaN`` and ``NaT``, i.e. they are treated as three different keys. However, for numeric Index all three are still coerced to a ``NaN`` (:issue:`22332`)
- Bug in `scalar in Index` if scalar is a float while the ``Index`` is of integer dtype (:issue:`22085`)

Missing
^^^^^^^
Expand Down
23 changes: 21 additions & 2 deletions pandas/core/indexes/numeric.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
pandas_dtype,
needs_i8_conversion,
is_integer_dtype,
is_float,
is_bool,
is_bool_dtype,
is_scalar)
Expand Down Expand Up @@ -162,7 +163,25 @@ def insert(self, loc, item):
)


class Int64Index(NumericIndex):
class IntegerIndex(NumericIndex):
"""
This is an abstract class for Int64Index, UInt64Index.
"""

def __contains__(self, key):
"""
Check if key is a float and has a decimal. If it has, return False.
"""
hash(key)
try:
if is_float(key) and int(key) != key:
return False
return key in self._engine
except (OverflowError, TypeError, ValueError):
return False


class Int64Index(IntegerIndex):
__doc__ = _num_index_shared_docs['class_descr'] % _int64_descr_args

_typ = 'int64index'
Expand Down Expand Up @@ -220,7 +239,7 @@ def _assert_safe_casting(cls, data, subarr):
)


class UInt64Index(NumericIndex):
class UInt64Index(IntegerIndex):
__doc__ = _num_index_shared_docs['class_descr'] % _uint64_descr_args

_typ = 'uint64index'
Expand Down
15 changes: 15 additions & 0 deletions pandas/tests/indexing/test_indexing.py
Original file line number Diff line number Diff line change
Expand Up @@ -631,6 +631,21 @@ def test_mixed_index_not_contains(self, index, val):
# GH 19860
assert val not in index

def test_contains_with_float_index(self):
# GH#22085
integer_index = pd.Int64Index([0, 1, 2, 3])
uinteger_index = pd.UInt64Index([0, 1, 2, 3])
float_index = pd.Float64Index([0.1, 1.1, 2.2, 3.3])

for index in (integer_index, uinteger_index):
assert 1.1 not in index
assert 1.0 in index
assert 1 in index

assert 1.1 in float_index
assert 1.0 not in float_index
assert 1 not in float_index

def test_index_type_coercion(self):

with catch_warnings(record=True):
Expand Down