Skip to content

Commit 26681db

Browse files
jschendeljreback
authored andcommitted
PERF: Implement RangeIndex min/max using RangeIndex properties (#17611)
1 parent 9732af2 commit 26681db

File tree

5 files changed

+73
-1
lines changed

5 files changed

+73
-1
lines changed

asv_bench/benchmarks/index_object.py

+20
Original file line numberDiff line numberDiff line change
@@ -199,3 +199,23 @@ def time_datetime_level_values_full(self):
199199

200200
def time_datetime_level_values_sliced(self):
201201
self.mi[:10].values
202+
203+
204+
class Range(object):
205+
goal_time = 0.2
206+
207+
def setup(self):
208+
self.idx_inc = RangeIndex(start=0, stop=10**7, step=3)
209+
self.idx_dec = RangeIndex(start=10**7, stop=-1, step=-3)
210+
211+
def time_max(self):
212+
self.idx_inc.max()
213+
214+
def time_max_trivial(self):
215+
self.idx_dec.max()
216+
217+
def time_min(self):
218+
self.idx_dec.min()
219+
220+
def time_min_trivial(self):
221+
self.idx_inc.min()

doc/source/api.rst

+14
Original file line numberDiff line numberDiff line change
@@ -1416,6 +1416,20 @@ Selecting
14161416
Index.slice_indexer
14171417
Index.slice_locs
14181418

1419+
.. _api.numericindex:
1420+
1421+
Numeric Index
1422+
-------------
1423+
1424+
.. autosummary::
1425+
:toctree: generated/
1426+
:template: autosummary/class_without_autosummary.rst
1427+
1428+
RangeIndex
1429+
Int64Index
1430+
UInt64Index
1431+
Float64Index
1432+
14191433
.. _api.categoricalindex:
14201434

14211435
CategoricalIndex

doc/source/whatsnew/v0.21.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,7 @@ Performance Improvements
473473
- Improved performance of :meth:`Categorical.set_categories` by not materializing the values (:issue:`17508`)
474474
- :attr:`Timestamp.microsecond` no longer re-computes on attribute access (:issue:`17331`)
475475
- Improved performance of the :class:`CategoricalIndex` for data that is already categorical dtype (:issue:`17513`)
476+
- Improved performance of :meth:`RangeIndex.min` and :meth:`RangeIndex.max` by using ``RangeIndex`` properties to perform the computations (:issue:`17607`)
476477

477478
.. _whatsnew_0210.bug_fixes:
478479

pandas/core/indexes/range.py

+18
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,24 @@ def copy(self, name=None, deep=False, dtype=None, **kwargs):
269269
return RangeIndex(name=name, fastpath=True,
270270
**dict(self._get_data_as_items()))
271271

272+
def _minmax(self, meth):
273+
no_steps = len(self) - 1
274+
if no_steps == -1:
275+
return np.nan
276+
elif ((meth == 'min' and self._step > 0) or
277+
(meth == 'max' and self._step < 0)):
278+
return self._start
279+
280+
return self._start + self._step * no_steps
281+
282+
def min(self):
283+
"""The minimum value of the RangeIndex"""
284+
return self._minmax('min')
285+
286+
def max(self):
287+
"""The maximum value of the RangeIndex"""
288+
return self._minmax('max')
289+
272290
def argsort(self, *args, **kwargs):
273291
"""
274292
Returns the indices that would sort the index and its

pandas/tests/indexes/test_range.py

+20-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
import numpy as np
1212

13-
from pandas import (notna, Series, Index, Float64Index,
13+
from pandas import (isna, notna, Series, Index, Float64Index,
1414
Int64Index, RangeIndex)
1515

1616
import pandas.util.testing as tm
@@ -994,3 +994,22 @@ def test_append(self):
994994
# Append single item rather than list
995995
result2 = indices[0].append(indices[1])
996996
tm.assert_index_equal(result2, expected, exact=True)
997+
998+
@pytest.mark.parametrize('start,stop,step',
999+
[(0, 400, 3), (500, 0, -6), (-10**6, 10**6, 4),
1000+
(10**6, -10**6, -4), (0, 10, 20)])
1001+
def test_max_min(self, start, stop, step):
1002+
# GH17607
1003+
idx = RangeIndex(start, stop, step)
1004+
expected = idx._int64index.max()
1005+
result = idx.max()
1006+
assert result == expected
1007+
1008+
expected = idx._int64index.min()
1009+
result = idx.min()
1010+
assert result == expected
1011+
1012+
# empty
1013+
idx = RangeIndex(start, stop, -step)
1014+
assert isna(idx.max())
1015+
assert isna(idx.min())

0 commit comments

Comments
 (0)