Skip to content

Commit acd7218

Browse files
authored
DEPR: Index.is_monotonic for Index.is_monotonic_increasing (#45422)
1 parent 90e512f commit acd7218

34 files changed

+143
-129
lines changed

asv_bench/benchmarks/index_cached_properties.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -56,9 +56,6 @@ def time_values(self, index_type):
5656
def time_shape(self, index_type):
5757
self.idx.shape
5858

59-
def time_is_monotonic(self, index_type):
60-
self.idx.is_monotonic
61-
6259
def time_is_monotonic_decreasing(self, index_type):
6360
self.idx.is_monotonic_decreasing
6461

asv_bench/benchmarks/multiindex_object.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ def time_get_indexer_and_pad(self):
112112
self.mi_int.get_indexer(self.other_mi_many_mismatches, method="pad")
113113

114114
def time_is_monotonic(self):
115-
self.mi_int.is_monotonic
115+
self.mi_int.is_monotonic_increasing
116116

117117

118118
class Duplicated:

doc/source/whatsnew/v1.5.0.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@ Other Deprecations
148148
- Deprecated behavior of :meth:`SparseArray.astype`, :meth:`Series.astype`, and :meth:`DataFrame.astype` with :class:`SparseDtype` when passing a non-sparse ``dtype``. In a future version, this will cast to that non-sparse dtype instead of wrapping it in a :class:`SparseDtype` (:issue:`34457`)
149149
- Deprecated behavior of :meth:`DatetimeIndex.intersection` and :meth:`DatetimeIndex.symmetric_difference` (``union`` behavior was already deprecated in version 1.3.0) with mixed timezones; in a future version both will be cast to UTC instead of object dtype (:issue:`39328`, :issue:`45357`)
150150
- Deprecated :meth:`DataFrame.iteritems`, :meth:`Series.iteritems`, :meth:`HDFStore.iteritems` in favor of :meth:`DataFrame.items`, :meth:`Series.items`, :meth:`HDFStore.items` (:issue:`45321`)
151+
- Deprecated :meth:`Series.is_monotonic` and :meth:`Index.is_monotonic` in favor of :meth:`Series.is_monotonic_increasing` and :meth:`Index.is_monotonic_increasing` (:issue:`45422`, :issue:`21335`)
151152
- Deprecated the ``__array_wrap__`` method of DataFrame and Series, rely on standard numpy ufuncs instead (:issue:`45451`)
152153
-
153154

pandas/core/base.py

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
final,
1717
overload,
1818
)
19+
import warnings
1920

2021
import numpy as np
2122

@@ -35,6 +36,7 @@
3536
cache_readonly,
3637
doc,
3738
)
39+
from pandas.util._exceptions import find_stack_level
3840

3941
from pandas.core.dtypes.common import (
4042
is_categorical_dtype,
@@ -1050,17 +1052,27 @@ def is_monotonic(self) -> bool:
10501052
-------
10511053
bool
10521054
"""
1053-
from pandas import Index
1054-
1055-
return Index(self).is_monotonic
1055+
warnings.warn(
1056+
"is_monotonic is deprecated and will be removed in a future version. "
1057+
"Use is_monotonic_increasing instead.",
1058+
FutureWarning,
1059+
stacklevel=find_stack_level(),
1060+
)
1061+
return self.is_monotonic_increasing
10561062

10571063
@property
10581064
def is_monotonic_increasing(self) -> bool:
10591065
"""
1060-
Alias for is_monotonic.
1066+
Return boolean if values in the object are
1067+
monotonic_increasing.
1068+
1069+
Returns
1070+
-------
1071+
bool
10611072
"""
1062-
# mypy complains if we alias directly
1063-
return self.is_monotonic
1073+
from pandas import Index
1074+
1075+
return Index(self).is_monotonic_increasing
10641076

10651077
@property
10661078
def is_monotonic_decreasing(self) -> bool:

pandas/core/generic.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7161,7 +7161,7 @@ def asof(self, where, subset=None):
71617161
if isinstance(where, str):
71627162
where = Timestamp(where)
71637163

7164-
if not self.index.is_monotonic:
7164+
if not self.index.is_monotonic_increasing:
71657165
raise ValueError("asof requires a sorted index")
71667166

71677167
is_series = isinstance(self, ABCSeries)

pandas/core/groupby/grouper.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,7 +400,7 @@ def _set_grouper(self, obj: NDFrame, sort: bool = False):
400400
raise ValueError(f"The level {level} is not valid")
401401

402402
# possibly sort
403-
if (self.sort or sort) and not ax.is_monotonic:
403+
if (self.sort or sort) and not ax.is_monotonic_increasing:
404404
# use stable sort to support first, last, nth
405405
# TODO: why does putting na_position="first" fix datetimelike cases?
406406
indexer = self.indexer = ax.array.argsort(

pandas/core/groupby/ops.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -823,7 +823,7 @@ def groups(self) -> dict[Hashable, np.ndarray]:
823823
@cache_readonly
824824
def is_monotonic(self) -> bool:
825825
# return if my group orderings are monotonic
826-
return Index(self.group_info[0]).is_monotonic
826+
return Index(self.group_info[0]).is_monotonic_increasing
827827

828828
@cache_readonly
829829
def group_info(self) -> tuple[npt.NDArray[np.intp], npt.NDArray[np.intp], int]:

pandas/core/indexes/base.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2200,6 +2200,12 @@ def is_monotonic(self) -> bool:
22002200
"""
22012201
Alias for is_monotonic_increasing.
22022202
"""
2203+
warnings.warn(
2204+
"is_monotonic is deprecated and will be removed in a future version. "
2205+
"Use is_monotonic_increasing instead.",
2206+
FutureWarning,
2207+
stacklevel=find_stack_level(),
2208+
)
22032209
return self.is_monotonic_increasing
22042210

22052211
@property
@@ -3263,8 +3269,8 @@ def _union(self, other: Index, sort):
32633269

32643270
if (
32653271
sort is None
3266-
and self.is_monotonic
3267-
and other.is_monotonic
3272+
and self.is_monotonic_increasing
3273+
and other.is_monotonic_increasing
32683274
and not (self.has_duplicates and other.has_duplicates)
32693275
and self._can_use_libjoin
32703276
):
@@ -3302,7 +3308,7 @@ def _union(self, other: Index, sort):
33023308
else:
33033309
result = lvals
33043310

3305-
if not self.is_monotonic or not other.is_monotonic:
3311+
if not self.is_monotonic_increasing or not other.is_monotonic_increasing:
33063312
# if both are monotonic then result should already be sorted
33073313
result = _maybe_try_sort(result, sort)
33083314

@@ -3407,7 +3413,11 @@ def _intersection(self, other: Index, sort=False):
34073413
"""
34083414
intersection specialized to the case with matching dtypes.
34093415
"""
3410-
if self.is_monotonic and other.is_monotonic and self._can_use_libjoin:
3416+
if (
3417+
self.is_monotonic_increasing
3418+
and other.is_monotonic_increasing
3419+
and self._can_use_libjoin
3420+
):
34113421
try:
34123422
result = self._inner_indexer(other)[0]
34133423
except TypeError:
@@ -4503,15 +4513,15 @@ def join(
45034513
if not self.is_unique and not other.is_unique:
45044514
return self._join_non_unique(other, how=how)
45054515
elif not self.is_unique or not other.is_unique:
4506-
if self.is_monotonic and other.is_monotonic:
4516+
if self.is_monotonic_increasing and other.is_monotonic_increasing:
45074517
if self._can_use_libjoin:
45084518
# otherwise we will fall through to _join_via_get_indexer
45094519
return self._join_monotonic(other, how=how)
45104520
else:
45114521
return self._join_non_unique(other, how=how)
45124522
elif (
4513-
self.is_monotonic
4514-
and other.is_monotonic
4523+
self.is_monotonic_increasing
4524+
and other.is_monotonic_increasing
45154525
and self._can_use_libjoin
45164526
and (
45174527
not isinstance(self, ABCMultiIndex)

pandas/core/indexes/multi.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1557,7 +1557,7 @@ def is_monotonic_increasing(self) -> bool:
15571557
if any(-1 in code for code in self.codes):
15581558
return False
15591559

1560-
if all(level.is_monotonic for level in self.levels):
1560+
if all(level.is_monotonic_increasing for level in self.levels):
15611561
# If each level is sorted, we can operate on the codes directly. GH27495
15621562
return libalgos.is_lexsorted(
15631563
[x.astype("int64", copy=False) for x in self.codes]
@@ -1574,11 +1574,11 @@ def is_monotonic_increasing(self) -> bool:
15741574
# int, float, complex, str, bytes, _NestedSequence[Union[bool, int, float,
15751575
# complex, str, bytes]]]" [arg-type]
15761576
sort_order = np.lexsort(values) # type: ignore[arg-type]
1577-
return Index(sort_order).is_monotonic
1577+
return Index(sort_order).is_monotonic_increasing
15781578
except TypeError:
15791579

15801580
# we have mixed types and np.lexsort is not happy
1581-
return Index(self._values).is_monotonic
1581+
return Index(self._values).is_monotonic_increasing
15821582

15831583
@cache_readonly
15841584
def is_monotonic_decreasing(self) -> bool:
@@ -1946,15 +1946,15 @@ def _sort_levels_monotonic(self) -> MultiIndex:
19461946
('b', 'bb')],
19471947
)
19481948
"""
1949-
if self._is_lexsorted() and self.is_monotonic:
1949+
if self._is_lexsorted() and self.is_monotonic_increasing:
19501950
return self
19511951

19521952
new_levels = []
19531953
new_codes = []
19541954

19551955
for lev, level_codes in zip(self.levels, self.codes):
19561956

1957-
if not lev.is_monotonic:
1957+
if not lev.is_monotonic_increasing:
19581958
try:
19591959
# indexer to reorder the levels
19601960
indexer = lev.argsort()

pandas/core/missing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def clean_interp_method(method: str, index: Index, **kwargs) -> str:
161161
raise ValueError(f"method must be one of {valid}. Got '{method}' instead.")
162162

163163
if method in ("krogh", "piecewise_polynomial", "pchip"):
164-
if not index.is_monotonic:
164+
if not index.is_monotonic_increasing:
165165
raise ValueError(
166166
f"{method} interpolation requires that the index be monotonic."
167167
)

0 commit comments

Comments
 (0)