Skip to content

Commit ef3bec2

Browse files
makbigcjreback
authored andcommitted
[PERF] Get rid of MultiIndex conversion in IntervalIndex.is_monotonic methods (#25820)
1 parent 258f787 commit ef3bec2

File tree

4 files changed

+32
-4
lines changed

4 files changed

+32
-4
lines changed

asv_bench/benchmarks/index_object.py

+15-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import numpy as np
22
import pandas.util.testing as tm
33
from pandas import (Series, date_range, DatetimeIndex, Index, RangeIndex,
4-
Float64Index)
4+
Float64Index, IntervalIndex)
55

66

77
class SetOperations:
@@ -181,4 +181,18 @@ def time_get_loc(self):
181181
self.ind.get_loc(0)
182182

183183

184+
class IntervalIndexMethod(object):
185+
# GH 24813
186+
params = [10**3, 10**5]
187+
188+
def setup(self, N):
189+
left = np.append(np.arange(N), np.array(0))
190+
right = np.append(np.arange(1, N + 1), np.array(1))
191+
self.intv = IntervalIndex.from_arrays(left, right)
192+
self.intv._engine
193+
194+
def time_monotonic_inc(self, N):
195+
self.intv.is_monotonic_increasing
196+
197+
184198
from .pandas_vb_common import setup # noqa: F401

doc/source/whatsnew/v0.25.0.rst

+1
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,7 @@ Performance Improvements
249249
- Improved performance of :meth:`pandas.core.groupby.GroupBy.quantile` (:issue:`20405`)
250250
- Improved performance of :meth:`read_csv` by faster tokenizing and faster parsing of small float numbers (:issue:`25784`)
251251
- Improved performance of :meth:`read_csv` by faster parsing of N/A and boolean values (:issue:`25804`)
252+
- Imporved performance of :meth:`IntervalIndex.is_monotonic`, :meth:`IntervalIndex.is_monotonic_increasing` and :meth:`IntervalIndex.is_monotonic_decreasing` by removing conversion to :class:`MultiIndex` (:issue:`24813`)
252253
- Improved performance of :meth:DataFrame.`to_csv` when write datetime dtype data (:issue:`25708`)
253254
- Improved performance of :meth:`read_csv` by much faster parsing of MM/YYYY and DD/MM/YYYY datetime formats (:issue:`25922`)
254255

pandas/_libs/intervaltree.pxi.in

+13
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ Template for intervaltree
44
WARNING: DO NOT edit .pxi FILE directly, .pxi is generated from .pxi.in
55
"""
66

7+
from pandas._libs.algos import is_monotonic
8+
79
ctypedef fused scalar_t:
810
float64_t
911
float32_t
@@ -101,6 +103,17 @@ cdef class IntervalTree(IntervalMixin):
101103

102104
return self._is_overlapping
103105

106+
@property
107+
def is_monotonic_increasing(self):
108+
"""
109+
Return True if the IntervalTree is monotonic increasing (only equal or
110+
increasing values), else False
111+
"""
112+
values = [self.right, self.left]
113+
114+
sort_order = np.lexsort(values)
115+
return is_monotonic(sort_order, False)[0]
116+
104117
def get_loc(self, scalar_t key):
105118
"""Return all positions corresponding to intervals that overlap with
106119
the given scalar key

pandas/core/indexes/interval.py

+3-3
Original file line numberDiff line numberDiff line change
@@ -438,23 +438,23 @@ def is_monotonic(self):
438438
Return True if the IntervalIndex is monotonic increasing (only equal or
439439
increasing values), else False
440440
"""
441-
return self._multiindex.is_monotonic
441+
return self.is_monotonic_increasing
442442

443443
@cache_readonly
444444
def is_monotonic_increasing(self):
445445
"""
446446
Return True if the IntervalIndex is monotonic increasing (only equal or
447447
increasing values), else False
448448
"""
449-
return self._multiindex.is_monotonic_increasing
449+
return self._engine.is_monotonic_increasing
450450

451451
@cache_readonly
452452
def is_monotonic_decreasing(self):
453453
"""
454454
Return True if the IntervalIndex is monotonic decreasing (only equal or
455455
decreasing values), else False
456456
"""
457-
return self._multiindex.is_monotonic_decreasing
457+
return self[::-1].is_monotonic_increasing
458458

459459
@cache_readonly
460460
def is_unique(self):

0 commit comments

Comments
 (0)