Skip to content

Commit d2de94e

Browse files
committed
PERF: custom ops for RangeIndex.[all|any|__contain__]
1 parent e0c41f7 commit d2de94e

File tree

4 files changed

+48
-10
lines changed

4 files changed

+48
-10
lines changed

pandas/core/common.py

+10
Original file line numberDiff line numberDiff line change
@@ -490,3 +490,13 @@ def f(x):
490490
f = mapper
491491

492492
return f
493+
494+
495+
def ensure_python_int(value: Union[int, Any]) -> int:
496+
msg = "Wrong type {} for value {}"
497+
try:
498+
new_value = int(value)
499+
assert (new_value == value)
500+
except (TypeError, ValueError, AssertionError):
501+
raise TypeError(msg.format(type(value), value))
502+
return new_value

pandas/core/indexes/base.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -4013,11 +4013,7 @@ def __contains__(self, key):
40134013

40144014
@Appender(_index_shared_docs['contains'] % _index_doc_kwargs)
40154015
def contains(self, key):
4016-
hash(key)
4017-
try:
4018-
return key in self._engine
4019-
except (TypeError, ValueError):
4020-
return False
4016+
return key in self
40214017

40224018
def __hash__(self):
40234019
raise TypeError("unhashable type: %r" % type(self).__name__)

pandas/core/indexes/range.py

+16-1
Original file line numberDiff line numberDiff line change
@@ -334,6 +334,14 @@ def is_monotonic_decreasing(self):
334334
def has_duplicates(self):
335335
return False
336336

337+
def __contains__(self, key):
338+
hash(key)
339+
try:
340+
key = com.ensure_python_int(key)
341+
except TypeError:
342+
return False
343+
return key in self._range
344+
337345
@Appender(_index_shared_docs['get_loc'])
338346
def get_loc(self, key, method=None, tolerance=None):
339347
if is_integer(key) and method is None and tolerance is None:
@@ -640,6 +648,14 @@ def __floordiv__(self, other):
640648
return self._simple_new(start, start + 1, 1, name=self.name)
641649
return self._int64index // other
642650

651+
def all(self) -> bool:
652+
if 0 in self._range:
653+
return False
654+
return True
655+
656+
def any(self) -> bool:
657+
return any(self._range)
658+
643659
@classmethod
644660
def _add_numeric_methods_binary(cls):
645661
""" add in numeric methods, specialized to RangeIndex """
@@ -725,4 +741,3 @@ def _evaluate_numeric_binop(self, other):
725741

726742

727743
RangeIndex._add_numeric_methods()
728-
RangeIndex._add_logical_methods()

pandas/tests/indexes/test_range.py

+21-4
Original file line numberDiff line numberDiff line change
@@ -245,10 +245,9 @@ def test_dtype(self):
245245
assert self.index.dtype == np.int64
246246

247247
def test_cached_data(self):
248-
# GH 26565
249-
# Calling RangeIndex._data caches an int64 array of the same length as
250-
# self at self._cached_data.
251-
# This tests whether _cached_data is being set by various operations.
248+
# GH 26565, GH26617
249+
# Calling RangeIndex._data caches an int64 array of the same length at
250+
# self._cached_data. This tests whether _cached_data has been set.
252251
idx = RangeIndex(0, 100, 10)
253252

254253
assert idx._cached_data is None
@@ -262,6 +261,24 @@ def test_cached_data(self):
262261
idx.get_loc(20)
263262
assert idx._cached_data is None
264263

264+
90 in idx
265+
assert idx._cached_data is None
266+
267+
91 in idx
268+
assert idx._cached_data is None
269+
270+
idx.contains(90)
271+
assert idx._cached_data is None
272+
273+
idx.contains(91)
274+
assert idx._cached_data is None
275+
276+
idx.all()
277+
assert idx._cached_data is None
278+
279+
idx.any()
280+
assert idx._cached_data is None
281+
265282
df = pd.DataFrame({'a': range(10)}, index=idx)
266283

267284
df.loc[50]

0 commit comments

Comments
 (0)