diff --git a/doc/source/whatsnew/v0.18.0.txt b/doc/source/whatsnew/v0.18.0.txt index b2eb7d9d97d58..160a2936cca70 100644 --- a/doc/source/whatsnew/v0.18.0.txt +++ b/doc/source/whatsnew/v0.18.0.txt @@ -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: diff --git a/pandas/core/index.py b/pandas/core/index.py index 63b748ada6afa..8459cbe3f810e 100644 --- a/pandas/core/index.py +++ b/pandas/core/index.py @@ -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 """ diff --git a/pandas/tests/test_index.py b/pandas/tests/test_index.py index 2c909d653df85..b0210c9fde2e9 100644 --- a/pandas/tests/test_index.py +++ b/pandas/tests/test_index.py @@ -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__ @@ -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) @@ -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)),