diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index bce6a735b7b07..888658eb5ed18 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -228,7 +228,7 @@ Datetimelike - Bug in :class:`DateOffset` where attributes reconstructed from pickle files differ from original objects when input values exceed normal ranges (e.g months=12) (:issue:`34511`) - Bug in :meth:`DatetimeIndex.get_slice_bound` where ``datetime.date`` objects were not accepted or naive :class:`Timestamp` with a tz-aware :class:`DatetimeIndex` (:issue:`35690`) - Bug in :meth:`DatetimeIndex.slice_locs` where ``datetime.date`` objects were not accepted (:issue:`34077`) -- Bug in :meth:`DatetimeIndex.searchsorted`, :meth:`TimedeltaIndex.searchsorted`, and :meth:`Series.searchsorted` with ``datetime64`` or ``timedelta64`` dtype placement of ``NaT`` values being inconsistent with ``NumPy`` (:issue:`36176`) +- Bug in :meth:`DatetimeIndex.searchsorted`, :meth:`TimedeltaIndex.searchsorted`, :meth:`PeriodIndex.searchsorted`, and :meth:`Series.searchsorted` with ``datetime64``, ``timedelta64`` or ``Period`` dtype placement of ``NaT`` values being inconsistent with ``NumPy`` (:issue:`36176`,:issue:`36254`) Timedelta ^^^^^^^^^ diff --git a/pandas/core/arrays/period.py b/pandas/core/arrays/period.py index 865b1680c008a..44c0455018a42 100644 --- a/pandas/core/arrays/period.py +++ b/pandas/core/arrays/period.py @@ -587,6 +587,13 @@ def astype(self, dtype, copy: bool = True): return self.asfreq(dtype.freq) return super().astype(dtype, copy=copy) + def searchsorted(self, value, side="left", sorter=None): + value = self._validate_searchsorted_value(value).view("M8[ns]") + + # Cast to M8 to get datetime-like NaT placement + m8arr = self._ndarray.view("M8[ns]") + return m8arr.searchsorted(value, side=side, sorter=sorter) + # ------------------------------------------------------------------ # Arithmetic Methods diff --git a/pandas/tests/arrays/test_datetimelike.py b/pandas/tests/arrays/test_datetimelike.py index 9d316c38082af..624335fd78b0f 100644 --- a/pandas/tests/arrays/test_datetimelike.py +++ b/pandas/tests/arrays/test_datetimelike.py @@ -244,7 +244,7 @@ def test_searchsorted(self): # GH#29884 match numpy convention on whether NaT goes # at the end or the beginning result = arr.searchsorted(pd.NaT) - if np_version_under1p18 or self.array_cls is PeriodArray: + if np_version_under1p18: # Following numpy convention, NaT goes at the beginning # (unlike NaN which goes at the end) assert result == 0 diff --git a/pandas/tests/indexes/period/test_searchsorted.py b/pandas/tests/indexes/period/test_searchsorted.py index f5a2583bf2e10..f2950b9f6065c 100644 --- a/pandas/tests/indexes/period/test_searchsorted.py +++ b/pandas/tests/indexes/period/test_searchsorted.py @@ -2,6 +2,7 @@ import pytest from pandas._libs.tslibs import IncompatibleFrequency +from pandas.compat.numpy import np_version_under1p18 from pandas import NaT, Period, PeriodIndex, Series, array import pandas._testing as tm @@ -21,7 +22,13 @@ def test_searchsorted(self, freq): p2 = Period("2014-01-04", freq=freq) assert pidx.searchsorted(p2) == 3 - assert pidx.searchsorted(NaT) == 0 + if np_version_under1p18: + # GH#36254 + # Following numpy convention, NaT goes at the beginning + # (unlike NaN which goes at the end) + assert pidx.searchsorted(NaT) == 0 + else: + assert pidx.searchsorted(NaT) == 5 msg = "Input has different freq=H from PeriodArray" with pytest.raises(IncompatibleFrequency, match=msg):