From 24004831bd951dc686a32c90dddf63549aa51681 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 29 Jan 2020 18:09:04 -0800 Subject: [PATCH 1/3] BUG: PeriodIndex.is_monotonic with leading NaT --- pandas/_libs/index.pyx | 3 +- pandas/tests/indexes/period/test_period.py | 40 ++++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/pandas/_libs/index.pyx b/pandas/_libs/index.pyx index 2dfc14378baf6..1915eaf6e07dd 100644 --- a/pandas/_libs/index.pyx +++ b/pandas/_libs/index.pyx @@ -514,8 +514,7 @@ cdef class PeriodEngine(Int64Engine): return super(PeriodEngine, self).vgetter().view("i8") cdef _call_monotonic(self, values): - # super(...) pattern doesn't seem to work with `cdef` - return Int64Engine._call_monotonic(self, values.view('i8')) + return algos.is_monotonic(values, timelike=True) def get_indexer(self, values): cdef: diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py index 16fa0b0c25925..f359463344531 100644 --- a/pandas/tests/indexes/period/test_period.py +++ b/pandas/tests/indexes/period/test_period.py @@ -662,3 +662,43 @@ def test_maybe_convert_timedelta(): msg = r"Input has different freq=B from PeriodIndex\(freq=D\)" with pytest.raises(ValueError, match=msg): pi._maybe_convert_timedelta(offset) + + +def test_is_monotonic_with_nat(): + # PeriodIndex.is_monotonic should behave analogously to DatetimeIndex, + # in particular never be monotonic when we have NaT + dti = pd.date_range("2016-01-01", periods=3) + pi = dti.to_period("D") + tdi = pd.Index(dti.view("timedelta64[ns]")) + + for obj in [pi, pi._engine, dti, dti._engine, tdi, tdi._engine]: + if isinstance(obj, pd.Index): + # i.e. not Engines + assert obj.is_monotonic + assert obj.is_monotonic_increasing + assert not obj.is_monotonic_decreasing + assert obj.is_unique + + dti1 = dti.insert(0, pd.NaT) + pi1 = dti1.to_period("D") + tdi1 = pd.Index(dti1.view("timedelta64[ns]")) + + for obj in [pi1, pi1._engine, dti1, dti1._engine, tdi1, tdi1._engine]: + if isinstance(obj, pd.Index): + # i.e. not Engines + assert not obj.is_monotonic + assert not obj.is_monotonic_increasing + assert not obj.is_monotonic_decreasing + assert obj.is_unique + + dti2 = dti.insert(3, pd.NaT) + pi2 = dti2.to_period("H") + tdi2 = pd.Index(dti2.view("timedelta64[ns]")) + + for obj in [pi2, pi2._engine, dti2, dti2._engine, tdi2, tdi2._engine]: + if isinstance(obj, pd.Index): + # i.e. not Engines + assert not obj.is_monotonic + assert not obj.is_monotonic_increasing + assert not obj.is_monotonic_decreasing + assert obj.is_unique From 4a89ebff84f34217f1952f1cb2d1144f2e427bb4 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 29 Jan 2020 18:10:54 -0800 Subject: [PATCH 2/3] GH ref --- doc/source/whatsnew/v1.1.0.rst | 2 +- pandas/tests/indexes/period/test_period.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v1.1.0.rst b/doc/source/whatsnew/v1.1.0.rst index 920919755dc23..6e13a76c68c1a 100644 --- a/doc/source/whatsnew/v1.1.0.rst +++ b/doc/source/whatsnew/v1.1.0.rst @@ -148,7 +148,7 @@ Indexing ^^^^^^^^ - Bug in slicing on a :class:`DatetimeIndex` with a partial-timestamp dropping high-resolution indices near the end of a year, quarter, or month (:issue:`31064`) - Bug in :meth:`PeriodIndex.get_loc` treating higher-resolution strings differently from :meth:`PeriodIndex.get_value` (:issue:`31172`) -- +- Bug in :meth:`PeriodIndex.is_monotonic` incorrectly returning ``True`` when containing leading ``NaT`` entries (:issue:`31437`) Missing ^^^^^^^ diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py index f359463344531..248df3291f040 100644 --- a/pandas/tests/indexes/period/test_period.py +++ b/pandas/tests/indexes/period/test_period.py @@ -665,6 +665,7 @@ def test_maybe_convert_timedelta(): def test_is_monotonic_with_nat(): + # GH#31437 # PeriodIndex.is_monotonic should behave analogously to DatetimeIndex, # in particular never be monotonic when we have NaT dti = pd.date_range("2016-01-01", periods=3) From effd825e7d5550472eeac1e82198529093079960 Mon Sep 17 00:00:00 2001 From: jbrockmendel Date: Wed, 29 Jan 2020 20:41:45 -0800 Subject: [PATCH 3/3] Fix incorrect test --- pandas/tests/reductions/test_reductions.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/pandas/tests/reductions/test_reductions.py b/pandas/tests/reductions/test_reductions.py index 8d2058ffab643..0b312fe2f8990 100644 --- a/pandas/tests/reductions/test_reductions.py +++ b/pandas/tests/reductions/test_reductions.py @@ -440,7 +440,8 @@ def test_minmax_period(self): # monotonic idx1 = pd.PeriodIndex([NaT, "2011-01-01", "2011-01-02", "2011-01-03"], freq="D") - assert idx1.is_monotonic + assert not idx1.is_monotonic + assert idx1[1:].is_monotonic # non-monotonic idx2 = pd.PeriodIndex(