Skip to content

ENH: GH12034 RangeIndex.__floordiv__ returns RangeIndex if possible #12070

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

Closed
wants to merge 1 commit into from
Closed
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
2 changes: 1 addition & 1 deletion doc/source/whatsnew/v0.18.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,7 @@ Range Index

A ``RangeIndex`` has been added to the ``Int64Index`` sub-classes to support a memory saving alternative for common use cases. This has a similar implementation to the python ``range`` object (``xrange`` in python 2), in that it only stores the start, stop, and step values for the index. It will transparently interact with the user API, converting to ``Int64Index`` if needed.

This will now be the default constructed index for ``NDFrame`` objects, rather than previous an ``Int64Index``. (:issue:`939`)
This will now be the default constructed index for ``NDFrame`` objects, rather than previous an ``Int64Index``. (:issue:`939`, :issue:`12070`)

Previous Behavior:

Expand Down
16 changes: 16 additions & 0 deletions pandas/core/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -4360,6 +4360,22 @@ def __getitem__(self, key):
# fall back to Int64Index
return super_getitem(key)

def __floordiv__(self, other):
if com.is_integer(other):
if (len(self) == 0 or
self._start % other == 0 and
self._step % other == 0):
start = self._start // other
step = self._step // other
stop = start + len(self) * step
return RangeIndex(start, stop, step, name=self.name,
fastpath=True)
if len(self) == 1:
start = self._start // other
return RangeIndex(start, start + 1, 1, name=self.name,
fastpath=True)
return self._int64index // other

@classmethod
def _add_numeric_methods_binary(cls):
""" add in numeric methods, specialized to RangeIndex """
Expand Down
24 changes: 13 additions & 11 deletions pandas/tests/test_index.py
Original file line number Diff line number Diff line change
Expand Up @@ -3733,7 +3733,7 @@ def test_numeric_compat2(self):
self.assertTrue(result.equals(expected))

result = idx // 1
expected = idx._int64index // 1
expected = idx
tm.assert_index_equal(result, expected, exact=True)

# __mul__
Expand All @@ -3748,15 +3748,18 @@ def test_numeric_compat2(self):
tm.assert_index_equal(Index(result.values), expected, exact=True)

# __floordiv__
idx = RangeIndex(0, 1000, 2)
result = idx // 2
expected = idx._int64index // 2
tm.assert_index_equal(result, expected, exact=True)

idx = RangeIndex(0, 1000, 1)
result = idx // 2
expected = idx._int64index // 2
tm.assert_index_equal(result, expected, exact=True)
cases_exact = [(RangeIndex(0, 1000, 2), 2, RangeIndex(0, 500, 1)),
(RangeIndex(-99, -201, -3), -3, RangeIndex(33, 67, 1)),
(RangeIndex(0, 1000, 1), 2,
RangeIndex(0, 1000, 1)._int64index // 2),
(RangeIndex(0, 100, 1), 2.0,
RangeIndex(0, 100, 1)._int64index // 2.0),
(RangeIndex(), 50, RangeIndex()),
(RangeIndex(2, 4, 2), 3, RangeIndex(0, 1, 1)),
(RangeIndex(-5, -10, -6), 4, RangeIndex(-2, -1, 1)),
(RangeIndex(-100, -200, 3), 2, RangeIndex())]
for idx, div, expected in cases_exact:
tm.assert_index_equal(idx // div, expected, exact=True)

def test_constructor_corner(self):
arr = np.array([1, 2, 3, 4], dtype=object)
Expand Down Expand Up @@ -3857,7 +3860,6 @@ def test_is_monotonic(self):
self.assertTrue(index.is_monotonic_decreasing)

def test_equals(self):

equiv_pairs = [(RangeIndex(0, 9, 2), RangeIndex(0, 10, 2)),
(RangeIndex(0), RangeIndex(1, -1, 3)),
(RangeIndex(1, 2, 3), RangeIndex(1, 3, 4)),
Expand Down