Skip to content

Commit 5a502b0

Browse files
mroeschkepmhatre1
authored andcommitted
PERF: RangeIndex.insert maintains RangeIndex when empty (pandas-dev#57833)
1 parent 1714f6a commit 5a502b0

File tree

3 files changed

+27
-15
lines changed

3 files changed

+27
-15
lines changed

doc/source/whatsnew/v3.0.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,7 @@ Performance improvements
277277
- Performance improvement in :meth:`RangeIndex.__getitem__` with a boolean mask or integers returning a :class:`RangeIndex` instead of a :class:`Index` when possible. (:issue:`57588`)
278278
- Performance improvement in :meth:`RangeIndex.append` when appending the same index (:issue:`57252`)
279279
- Performance improvement in :meth:`RangeIndex.argmin` and :meth:`RangeIndex.argmax` (:issue:`57823`)
280+
- Performance improvement in :meth:`RangeIndex.insert` returning a :class:`RangeIndex` instead of a :class:`Index` when the :class:`RangeIndex` is empty. (:issue:`57833`)
280281
- Performance improvement in :meth:`RangeIndex.round` returning a :class:`RangeIndex` instead of a :class:`Index` when possible. (:issue:`57824`)
281282
- Performance improvement in :meth:`RangeIndex.join` returning a :class:`RangeIndex` instead of a :class:`Index` when possible. (:issue:`57651`, :issue:`57752`)
282283
- Performance improvement in :meth:`RangeIndex.reindex` returning a :class:`RangeIndex` instead of a :class:`Index` when possible. (:issue:`57647`, :issue:`57752`)

pandas/core/indexes/range.py

+19-15
Original file line numberDiff line numberDiff line change
@@ -396,7 +396,7 @@ def __contains__(self, key: Any) -> bool:
396396
hash(key)
397397
try:
398398
key = ensure_python_int(key)
399-
except TypeError:
399+
except (TypeError, OverflowError):
400400
return False
401401
return key in self._range
402402

@@ -1009,23 +1009,27 @@ def delete(self, loc) -> Index: # type: ignore[override]
10091009
return super().delete(loc)
10101010

10111011
def insert(self, loc: int, item) -> Index:
1012-
if len(self) and (is_integer(item) or is_float(item)):
1012+
if is_integer(item) or is_float(item):
10131013
# We can retain RangeIndex is inserting at the beginning or end,
10141014
# or right in the middle.
1015-
rng = self._range
1016-
if loc == 0 and item == self[0] - self.step:
1017-
new_rng = range(rng.start - rng.step, rng.stop, rng.step)
1018-
return type(self)._simple_new(new_rng, name=self._name)
1019-
1020-
elif loc == len(self) and item == self[-1] + self.step:
1021-
new_rng = range(rng.start, rng.stop + rng.step, rng.step)
1022-
return type(self)._simple_new(new_rng, name=self._name)
1023-
1024-
elif len(self) == 2 and item == self[0] + self.step / 2:
1025-
# e.g. inserting 1 into [0, 2]
1026-
step = int(self.step / 2)
1027-
new_rng = range(self.start, self.stop, step)
1015+
if len(self) == 0 and loc == 0 and is_integer(item):
1016+
new_rng = range(item, item + self.step, self.step)
10281017
return type(self)._simple_new(new_rng, name=self._name)
1018+
elif len(self):
1019+
rng = self._range
1020+
if loc == 0 and item == self[0] - self.step:
1021+
new_rng = range(rng.start - rng.step, rng.stop, rng.step)
1022+
return type(self)._simple_new(new_rng, name=self._name)
1023+
1024+
elif loc == len(self) and item == self[-1] + self.step:
1025+
new_rng = range(rng.start, rng.stop + rng.step, rng.step)
1026+
return type(self)._simple_new(new_rng, name=self._name)
1027+
1028+
elif len(self) == 2 and item == self[0] + self.step / 2:
1029+
# e.g. inserting 1 into [0, 2]
1030+
step = int(self.step / 2)
1031+
new_rng = range(self.start, self.stop, step)
1032+
return type(self)._simple_new(new_rng, name=self._name)
10291033

10301034
return super().insert(loc, item)
10311035

pandas/tests/indexes/ranges/test_range.py

+7
Original file line numberDiff line numberDiff line change
@@ -659,6 +659,13 @@ def test_reindex_empty_returns_rangeindex():
659659
tm.assert_numpy_array_equal(result_indexer, expected_indexer)
660660

661661

662+
def test_insert_empty_0_loc():
663+
ri = RangeIndex(0, step=10, name="foo")
664+
result = ri.insert(0, 5)
665+
expected = RangeIndex(5, 15, 10, name="foo")
666+
tm.assert_index_equal(result, expected, exact=True)
667+
668+
662669
def test_append_non_rangeindex_return_rangeindex():
663670
ri = RangeIndex(1)
664671
result = ri.append(Index([1]))

0 commit comments

Comments
 (0)