Skip to content

Commit 8bca43c

Browse files
committed
PERF: custom ops for RangeIndex.[all|any|__contain__]
1 parent 437efa6 commit 8bca43c

File tree

4 files changed

+49
-7
lines changed

4 files changed

+49
-7
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

+19-1
Original file line numberDiff line numberDiff line change
@@ -315,6 +315,14 @@ def is_monotonic_decreasing(self):
315315
def has_duplicates(self):
316316
return False
317317

318+
def __contains__(self, key):
319+
hash(key)
320+
try:
321+
key = com.ensure_python_int(key)
322+
except TypeError:
323+
return False
324+
return key in self._range
325+
318326
@Appender(_index_shared_docs['get_loc'])
319327
def get_loc(self, key, method=None, tolerance=None):
320328
if is_integer(key) and method is None and tolerance is None:
@@ -673,6 +681,17 @@ def __floordiv__(self, other):
673681
start, start + 1, 1, name=self.name)
674682
return self._int64index // other
675683

684+
def all(self) -> bool:
685+
if 0 in self._range:
686+
return False
687+
return True
688+
689+
def any(self) -> bool:
690+
rng = self._range
691+
if len(rng) == 0 or (len(rng) == 1 and 0 in rng):
692+
return False
693+
return True
694+
676695
@classmethod
677696
def _add_numeric_methods_binary(cls):
678697
""" add in numeric methods, specialized to RangeIndex """
@@ -761,4 +780,3 @@ def _evaluate_numeric_binop(self, other):
761780

762781

763782
RangeIndex._add_numeric_methods()
764-
RangeIndex._add_logical_methods()

pandas/tests/indexes/test_range.py

+19-1
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,24 @@ def test_cached_data(self):
258258
idx.get_loc(20)
259259
assert idx._cached_data is None
260260

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

263281
df.loc[50]
@@ -273,7 +291,7 @@ def test_cached_data(self):
273291
df.iloc[5:10]
274292
assert idx._cached_data is None
275293

276-
# actually calling data._data
294+
# actually calling idx._data
277295
assert isinstance(idx._data, np.ndarray)
278296
assert isinstance(idx._cached_data, np.ndarray)
279297

0 commit comments

Comments
 (0)