Skip to content

Commit d5ed4d8

Browse files
is_monotonic to python
1 parent 1336afb commit d5ed4d8

File tree

2 files changed

+47
-90
lines changed

2 files changed

+47
-90
lines changed

pandas/_libs_numba/algos.py

Lines changed: 43 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -794,92 +794,51 @@ def _pad_inplace_with_limit(values: np.ndarray, mask: np.ndarray, limit: int) ->
794794
# val = values[j, i]
795795

796796

797-
# @cython.boundscheck(False)
798-
# @cython.wraparound(False)
799-
# def is_monotonic(ndarray[algos_t, ndim=1] arr, bint timelike):
800-
# """
801-
# Returns
802-
# -------
803-
# tuple
804-
# is_monotonic_inc : bool
805-
# is_monotonic_dec : bool
806-
# is_unique : bool
807-
# """
808-
# cdef:
809-
# Py_ssize_t i, n
810-
# algos_t prev, cur
811-
# bint is_monotonic_inc = 1
812-
# bint is_monotonic_dec = 1
813-
# bint is_unique = 1
814-
# bint is_strict_monotonic = 1
815-
816-
# n = len(arr)
817-
818-
# if n == 1:
819-
# if arr[0] != arr[0] or (timelike and <int64_t>arr[0] == NPY_NAT):
820-
# # single value is NaN
821-
# return False, False, True
822-
# else:
823-
# return True, True, True
824-
# elif n < 2:
825-
# return True, True, True
797+
def is_monotonic(arr: np.ndarray) -> tuple[bool, bool, bool]:
798+
"""
799+
Returns
800+
-------
801+
tuple
802+
is_monotonic_inc : bool
803+
is_monotonic_dec : bool
804+
is_unique : bool
805+
"""
806+
is_monotonic_inc = True
807+
is_monotonic_dec = True
808+
is_unique = True
809+
is_strict_monotonic = True
826810

827-
# if timelike and <int64_t>arr[0] == NPY_NAT:
828-
# return False, False, True
811+
n = len(arr)
829812

830-
# if algos_t is not object:
831-
# with nogil:
832-
# prev = arr[0]
833-
# for i in range(1, n):
834-
# cur = arr[i]
835-
# if timelike and <int64_t>cur == NPY_NAT:
836-
# is_monotonic_inc = 0
837-
# is_monotonic_dec = 0
838-
# break
839-
# if cur < prev:
840-
# is_monotonic_inc = 0
841-
# elif cur > prev:
842-
# is_monotonic_dec = 0
843-
# elif cur == prev:
844-
# is_unique = 0
845-
# else:
846-
# # cur or prev is NaN
847-
# is_monotonic_inc = 0
848-
# is_monotonic_dec = 0
849-
# break
850-
# if not is_monotonic_inc and not is_monotonic_dec:
851-
# is_monotonic_inc = 0
852-
# is_monotonic_dec = 0
853-
# break
854-
# prev = cur
855-
# else:
856-
# # object-dtype, identical to above except we cannot use `with nogil`
857-
# prev = arr[0]
858-
# for i in range(1, n):
859-
# cur = arr[i]
860-
# if timelike and <int64_t>cur == NPY_NAT:
861-
# is_monotonic_inc = 0
862-
# is_monotonic_dec = 0
863-
# break
864-
# if cur < prev:
865-
# is_monotonic_inc = 0
866-
# elif cur > prev:
867-
# is_monotonic_dec = 0
868-
# elif cur == prev:
869-
# is_unique = 0
870-
# else:
871-
# # cur or prev is NaN
872-
# is_monotonic_inc = 0
873-
# is_monotonic_dec = 0
874-
# break
875-
# if not is_monotonic_inc and not is_monotonic_dec:
876-
# is_monotonic_inc = 0
877-
# is_monotonic_dec = 0
878-
# break
879-
# prev = cur
880-
881-
# is_strict_monotonic = is_unique and (is_monotonic_inc or is_monotonic_dec)
882-
# return is_monotonic_inc, is_monotonic_dec, is_strict_monotonic
813+
if n == 1:
814+
if arr[0] != arr[0]:
815+
# single value is NaN/NaT
816+
return False, False, True
817+
else:
818+
return True, True, True
819+
elif n < 2:
820+
return True, True, True
821+
822+
prev = arr[0]
823+
for i in range(1, n):
824+
cur = arr[i]
825+
if cur < prev:
826+
is_monotonic_inc = False
827+
elif cur > prev:
828+
is_monotonic_dec = False
829+
elif cur == prev:
830+
is_unique = False
831+
else:
832+
# cur or prev is NaN/NaT
833+
is_monotonic_inc = False
834+
is_monotonic_dec = False
835+
break
836+
if not is_monotonic_inc and not is_monotonic_dec:
837+
break
838+
prev = cur
839+
840+
is_strict_monotonic = is_unique and (is_monotonic_inc or is_monotonic_dec)
841+
return is_monotonic_inc, is_monotonic_dec, is_strict_monotonic
883842

884843

885844
# # ----------------------------------------------------------------------

pandas/core/arrays/datetimelike.py

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,7 @@
2121

2222
import numpy as np
2323

24-
from pandas._libs import (
25-
algos,
26-
lib,
27-
)
24+
from pandas._libs import lib
2825
from pandas._libs.tslibs import (
2926
BaseOffset,
3027
IncompatibleFrequency,
@@ -43,6 +40,7 @@
4340
round_nsint64,
4441
)
4542
from pandas._libs.tslibs.timestamps import integer_op_not_supported
43+
from pandas._libs_numba import algos
4644
from pandas._typing import (
4745
DatetimeLikeScalar,
4846
Dtype,
@@ -961,11 +959,11 @@ def _generate_range(
961959

962960
@property
963961
def _is_monotonic_increasing(self) -> bool:
964-
return algos.is_monotonic(self.asi8, timelike=True)[0]
962+
return algos.is_monotonic(self._data)[0]
965963

966964
@property
967965
def _is_monotonic_decreasing(self) -> bool:
968-
return algos.is_monotonic(self.asi8, timelike=True)[1]
966+
return algos.is_monotonic(self._data)[1]
969967

970968
@property
971969
def _is_unique(self) -> bool:

0 commit comments

Comments
 (0)