Skip to content

PERF: RangeIndex.is_monotonic_inc/dec #13749

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
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.19.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -649,6 +649,7 @@ Performance Improvements
- Improved performance of float64 hash table operations, fixing some very slow indexing and groupby operations in python 3 (:issue:`13166`, :issue:`13334`)
- Improved performance of ``DataFrameGroupBy.transform`` (:issue:`12737`)
- Improved performance of ``Index.difference`` (:issue:`12044`)
- Improved performance of ``RangeIndex.is_monotonic_increasing`` and ``is_monotonic_decreasing`` (:issue:`13749`)
- Improved performance of datetime string parsing in ``DatetimeIndex`` (:issue:`13692`)
- Improved performance of hashing ``Period`` (:issue:`12817`)

Expand Down
8 changes: 8 additions & 0 deletions pandas/indexes/range.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,14 @@ def is_unique(self):
""" return if the index has unique values """
return True

@cache_readonly
def is_monotonic_increasing(self):
return self._step > 0 or len(self) <= 1

@cache_readonly
def is_monotonic_decreasing(self):
return self._step < 0 or len(self) <= 1

@property
def has_duplicates(self):
return False
Expand Down
10 changes: 10 additions & 0 deletions pandas/tests/indexes/test_range.py
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,16 @@ def test_is_monotonic(self):
self.assertTrue(index.is_monotonic_increasing)
self.assertTrue(index.is_monotonic_decreasing)

index = RangeIndex(2, 1)
self.assertTrue(index.is_monotonic)
self.assertTrue(index.is_monotonic_increasing)
self.assertTrue(index.is_monotonic_decreasing)

index = RangeIndex(1, 1)
self.assertTrue(index.is_monotonic)
self.assertTrue(index.is_monotonic_increasing)
self.assertTrue(index.is_monotonic_decreasing)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe add a test for the empty case as well?

In [23]: pd.RangeIndex().is_monotonic_increasing
Out[23]: True

In [24]: pd.RangeIndex().is_monotonic_decreasing
Out[24]: True

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Although this should maybe rather raise an error (@jreback)

Other index types to raise without arguments, and range() does as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jorisvandenbossche empty case is coverd by (1, 1).

pd.RangeIndex(1, 1).values
# array([], dtype=int64)

Let me issue a separate PR to prohibit empty construction.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah yes, assumed that RangeIndex() does not has a step yet, but that is of course wrong :-)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah I don't think RangeIndex() should be permitted, though I seem to remember needing it for unpickling or somesuch.......

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let's make a new issue about the empty RangeIndex()

def test_equals(self):
equiv_pairs = [(RangeIndex(0, 9, 2), RangeIndex(0, 10, 2)),
(RangeIndex(0), RangeIndex(1, -1, 3)),
Expand Down