diff --git a/doc/source/advanced.rst b/doc/source/advanced.rst index ea00588ba156f..711c3e9a95d05 100644 --- a/doc/source/advanced.rst +++ b/doc/source/advanced.rst @@ -948,6 +948,16 @@ On the other hand, if the index is not monotonic, then both slice bounds must be In [11]: df.loc[2:3, :] KeyError: 'Cannot get right slice bound for non-unique label: 3' +:meth:`Index.is_monotonic_increasing` and :meth:`Index.is_monotonic_decreasing` only check that +an index is weakly monotonic. To check for strict montonicity, you can combine one of those with +:meth:`Index.is_unique` + +.. ipython:: python + + weakly_monotonic = pd.Index(['a', 'b', 'c', 'c']) + weakly_monotonic + weakly_monotonic.is_monotonic_increasing + weakly_monotonic.is_monotonic_increasing & weakly_monotonic.is_unique Endpoints are inclusive ~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/doc/source/api.rst b/doc/source/api.rst index e210849d9a0ca..888bb6d67e94b 100644 --- a/doc/source/api.rst +++ b/doc/source/api.rst @@ -1286,8 +1286,6 @@ Attributes Index.is_monotonic Index.is_monotonic_increasing Index.is_monotonic_decreasing - Index.is_strictly_monotonic_increasing - Index.is_strictly_monotonic_decreasing Index.is_unique Index.has_duplicates Index.dtype diff --git a/doc/source/whatsnew/v0.20.2.txt b/doc/source/whatsnew/v0.20.2.txt index 379249b6e55d6..d2f2add578d5b 100644 --- a/doc/source/whatsnew/v0.20.2.txt +++ b/doc/source/whatsnew/v0.20.2.txt @@ -21,7 +21,6 @@ Enhancements - Unblocked access to additional compression types supported in pytables: 'blosc:blosclz, 'blosc:lz4', 'blosc:lz4hc', 'blosc:snappy', 'blosc:zlib', 'blosc:zstd' (:issue:`14478`) - ``Series`` provides a ``to_latex`` method (:issue:`16180`) -- Added :attr:`Index.is_strictly_monotonic_increasing` and :attr:`Index.is_strictly_monotonic_decreasing` properties (:issue:`16515`) .. _whatsnew_0202.performance: diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index e8c2043138edb..028464ad5cd89 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1221,33 +1221,33 @@ def is_monotonic_decreasing(self): return self._engine.is_monotonic_decreasing @property - def is_strictly_monotonic_increasing(self): + def _is_strictly_monotonic_increasing(self): """return if the index is strictly monotonic increasing (only increasing) values Examples -------- - >>> Index([1, 2, 3]).is_strictly_monotonic_increasing + >>> Index([1, 2, 3])._is_strictly_monotonic_increasing True - >>> Index([1, 2, 2]).is_strictly_monotonic_increasing + >>> Index([1, 2, 2])._is_strictly_monotonic_increasing False - >>> Index([1, 3, 2]).is_strictly_monotonic_increasing + >>> Index([1, 3, 2])._is_strictly_monotonic_increasing False """ return self.is_unique and self.is_monotonic_increasing @property - def is_strictly_monotonic_decreasing(self): + def _is_strictly_monotonic_decreasing(self): """return if the index is strictly monotonic decreasing (only decreasing) values Examples -------- - >>> Index([3, 2, 1]).is_strictly_monotonic_decreasing + >>> Index([3, 2, 1])._is_strictly_monotonic_decreasing True - >>> Index([3, 2, 2]).is_strictly_monotonic_decreasing + >>> Index([3, 2, 2])._is_strictly_monotonic_decreasing False - >>> Index([3, 1, 2]).is_strictly_monotonic_decreasing + >>> Index([3, 1, 2])._is_strictly_monotonic_decreasing False """ return self.is_unique and self.is_monotonic_decreasing diff --git a/pandas/core/indexes/datetimes.py b/pandas/core/indexes/datetimes.py index 60560374cd420..239894cff3874 100644 --- a/pandas/core/indexes/datetimes.py +++ b/pandas/core/indexes/datetimes.py @@ -1472,7 +1472,7 @@ def _maybe_cast_slice_bound(self, label, side, kind): # the bounds need swapped if index is reverse sorted and has a # length > 1 (is_monotonic_decreasing gives True for empty # and length 1 index) - if self.is_strictly_monotonic_decreasing and len(self) > 1: + if self._is_strictly_monotonic_decreasing and len(self) > 1: return upper if side == 'left' else lower return lower if side == 'left' else upper else: diff --git a/pandas/tests/indexes/test_base.py b/pandas/tests/indexes/test_base.py index a6933316e4291..d9f8e5e7f382b 100644 --- a/pandas/tests/indexes/test_base.py +++ b/pandas/tests/indexes/test_base.py @@ -1330,8 +1330,8 @@ def test_is_monotonic_incomparable(self): index = Index([5, datetime.now(), 7]) assert not index.is_monotonic_increasing assert not index.is_monotonic_decreasing - assert not index.is_strictly_monotonic_increasing - assert not index.is_strictly_monotonic_decreasing + assert not index._is_strictly_monotonic_increasing + assert not index._is_strictly_monotonic_decreasing def test_get_set_value(self): values = np.random.randn(100) @@ -2030,8 +2030,8 @@ def test_is_monotonic_na(self): for index in examples: assert not index.is_monotonic_increasing assert not index.is_monotonic_decreasing - assert not index.is_strictly_monotonic_increasing - assert not index.is_strictly_monotonic_decreasing + assert not index._is_strictly_monotonic_increasing + assert not index._is_strictly_monotonic_decreasing def test_repr_summary(self): with cf.option_context('display.max_seq_items', 10): diff --git a/pandas/tests/indexes/test_multi.py b/pandas/tests/indexes/test_multi.py index 388a49d25cb82..7e764bc73d2fa 100644 --- a/pandas/tests/indexes/test_multi.py +++ b/pandas/tests/indexes/test_multi.py @@ -2373,30 +2373,30 @@ def test_is_monotonic(self): i = MultiIndex.from_product([np.arange(10), np.arange(10)], names=['one', 'two']) assert i.is_monotonic - assert i.is_strictly_monotonic_increasing + assert i._is_strictly_monotonic_increasing assert Index(i.values).is_monotonic - assert i.is_strictly_monotonic_increasing + assert i._is_strictly_monotonic_increasing i = MultiIndex.from_product([np.arange(10, 0, -1), np.arange(10)], names=['one', 'two']) assert not i.is_monotonic - assert not i.is_strictly_monotonic_increasing + assert not i._is_strictly_monotonic_increasing assert not Index(i.values).is_monotonic - assert not Index(i.values).is_strictly_monotonic_increasing + assert not Index(i.values)._is_strictly_monotonic_increasing i = MultiIndex.from_product([np.arange(10), np.arange(10, 0, -1)], names=['one', 'two']) assert not i.is_monotonic - assert not i.is_strictly_monotonic_increasing + assert not i._is_strictly_monotonic_increasing assert not Index(i.values).is_monotonic - assert not Index(i.values).is_strictly_monotonic_increasing + assert not Index(i.values)._is_strictly_monotonic_increasing i = MultiIndex.from_product([[1.0, np.nan, 2.0], ['a', 'b', 'c']]) assert not i.is_monotonic - assert not i.is_strictly_monotonic_increasing + assert not i._is_strictly_monotonic_increasing assert not Index(i.values).is_monotonic - assert not Index(i.values).is_strictly_monotonic_increasing + assert not Index(i.values)._is_strictly_monotonic_increasing # string ordering i = MultiIndex(levels=[['foo', 'bar', 'baz', 'qux'], @@ -2406,8 +2406,8 @@ def test_is_monotonic(self): names=['first', 'second']) assert not i.is_monotonic assert not Index(i.values).is_monotonic - assert not i.is_strictly_monotonic_increasing - assert not Index(i.values).is_strictly_monotonic_increasing + assert not i._is_strictly_monotonic_increasing + assert not Index(i.values)._is_strictly_monotonic_increasing i = MultiIndex(levels=[['bar', 'baz', 'foo', 'qux'], ['mom', 'next', 'zenith']], @@ -2416,8 +2416,8 @@ def test_is_monotonic(self): names=['first', 'second']) assert i.is_monotonic assert Index(i.values).is_monotonic - assert i.is_strictly_monotonic_increasing - assert Index(i.values).is_strictly_monotonic_increasing + assert i._is_strictly_monotonic_increasing + assert Index(i.values)._is_strictly_monotonic_increasing # mixed levels, hits the TypeError i = MultiIndex( @@ -2428,20 +2428,20 @@ def test_is_monotonic(self): names=['household_id', 'asset_id']) assert not i.is_monotonic - assert not i.is_strictly_monotonic_increasing + assert not i._is_strictly_monotonic_increasing def test_is_strictly_monotonic(self): idx = pd.MultiIndex(levels=[['bar', 'baz'], ['mom', 'next']], labels=[[0, 0, 1, 1], [0, 0, 0, 1]]) assert idx.is_monotonic_increasing - assert not idx.is_strictly_monotonic_increasing + assert not idx._is_strictly_monotonic_increasing @pytest.mark.xfail(reason="buggy MultiIndex.is_monotonic_decresaing.") - def test_is_strictly_monotonic_decreasing(self): + def test__is_strictly_monotonic_decreasing(self): idx = pd.MultiIndex(levels=[['baz', 'bar'], ['next', 'mom']], labels=[[0, 0, 1, 1], [0, 0, 0, 1]]) assert idx.is_monotonic_decreasing - assert not idx.is_strictly_monotonic_decreasing + assert not idx._is_strictly_monotonic_decreasing def test_reconstruct_sort(self): diff --git a/pandas/tests/indexes/test_numeric.py b/pandas/tests/indexes/test_numeric.py index 77f34dbf210e0..29d4214fd549b 100644 --- a/pandas/tests/indexes/test_numeric.py +++ b/pandas/tests/indexes/test_numeric.py @@ -465,36 +465,36 @@ def test_view(self): def test_is_monotonic(self): assert self.index.is_monotonic assert self.index.is_monotonic_increasing - assert self.index.is_strictly_monotonic_increasing + assert self.index._is_strictly_monotonic_increasing assert not self.index.is_monotonic_decreasing - assert not self.index.is_strictly_monotonic_decreasing + assert not self.index._is_strictly_monotonic_decreasing index = self._holder([4, 3, 2, 1]) assert not index.is_monotonic - assert not index.is_strictly_monotonic_increasing - assert index.is_strictly_monotonic_decreasing + assert not index._is_strictly_monotonic_increasing + assert index._is_strictly_monotonic_decreasing index = self._holder([1]) assert index.is_monotonic assert index.is_monotonic_increasing assert index.is_monotonic_decreasing - assert index.is_strictly_monotonic_increasing - assert index.is_strictly_monotonic_decreasing + assert index._is_strictly_monotonic_increasing + assert index._is_strictly_monotonic_decreasing def test_is_strictly_monotonic(self): index = self._holder([1, 1, 2, 3]) assert index.is_monotonic_increasing - assert not index.is_strictly_monotonic_increasing + assert not index._is_strictly_monotonic_increasing index = self._holder([3, 2, 1, 1]) assert index.is_monotonic_decreasing - assert not index.is_strictly_monotonic_decreasing + assert not index._is_strictly_monotonic_decreasing index = self._holder([1, 1]) assert index.is_monotonic_increasing assert index.is_monotonic_decreasing - assert not index.is_strictly_monotonic_increasing - assert not index.is_strictly_monotonic_decreasing + assert not index._is_strictly_monotonic_increasing + assert not index._is_strictly_monotonic_decreasing def test_logical_compat(self): idx = self.create_index() diff --git a/pandas/tests/indexes/test_range.py b/pandas/tests/indexes/test_range.py index db8180cb736c4..0d88e88030604 100644 --- a/pandas/tests/indexes/test_range.py +++ b/pandas/tests/indexes/test_range.py @@ -331,35 +331,35 @@ def test_is_monotonic(self): assert self.index.is_monotonic assert self.index.is_monotonic_increasing assert not self.index.is_monotonic_decreasing - assert self.index.is_strictly_monotonic_increasing - assert not self.index.is_strictly_monotonic_decreasing + assert self.index._is_strictly_monotonic_increasing + assert not self.index._is_strictly_monotonic_decreasing index = RangeIndex(4, 0, -1) assert not index.is_monotonic - assert not index.is_strictly_monotonic_increasing + assert not index._is_strictly_monotonic_increasing assert index.is_monotonic_decreasing - assert index.is_strictly_monotonic_decreasing + assert index._is_strictly_monotonic_decreasing index = RangeIndex(1, 2) assert index.is_monotonic assert index.is_monotonic_increasing assert index.is_monotonic_decreasing - assert index.is_strictly_monotonic_increasing - assert index.is_strictly_monotonic_decreasing + assert index._is_strictly_monotonic_increasing + assert index._is_strictly_monotonic_decreasing index = RangeIndex(2, 1) assert index.is_monotonic assert index.is_monotonic_increasing assert index.is_monotonic_decreasing - assert index.is_strictly_monotonic_increasing - assert index.is_strictly_monotonic_decreasing + assert index._is_strictly_monotonic_increasing + assert index._is_strictly_monotonic_decreasing index = RangeIndex(1, 1) assert index.is_monotonic assert index.is_monotonic_increasing assert index.is_monotonic_decreasing - assert index.is_strictly_monotonic_increasing - assert index.is_strictly_monotonic_decreasing + assert index._is_strictly_monotonic_increasing + assert index._is_strictly_monotonic_decreasing def test_equals_range(self): equiv_pairs = [(RangeIndex(0, 9, 2), RangeIndex(0, 10, 2)),