From e105d324296831370759ba0b03885dfad7a64b6f Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 20 Nov 2020 14:32:46 -0800 Subject: [PATCH 1/2] DEPR: how keyword in PeriodIndex.astype --- doc/source/whatsnew/v1.2.0.rst | 1 + pandas/core/indexes/period.py | 17 ++++++++++++++--- pandas/tests/indexes/period/test_astype.py | 12 +++++++++--- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index ecea79be5b4dc..17f220f1c2fae 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -476,6 +476,7 @@ Deprecations - :meth:`Categorical.is_dtype_equal` and :meth:`CategoricalIndex.is_dtype_equal` are deprecated, will be removed in a future version (:issue:`37545`) - :meth:`Series.slice_shift` and :meth:`DataFrame.slice_shift` are deprecated, use :meth:`Series.shift` or :meth:`DataFrame.shift` instead (:issue:`37601`) - Partial slicing on unordered :class:`DatetimeIndex` with keys, which are not in Index is deprecated and will be removed in a future version (:issue:`18531`) +- The ``how`` keyword in :meth:`PeriodIndex.astype` is deprecated and will be removed in a future version, use ``index.to_timestamp(how=how)`` instead (:issue:`???`) - Deprecated :meth:`Index.asi8` for :class:`Index` subclasses other than :class:`DatetimeIndex`, :class:`TimedeltaIndex`, and :class:`PeriodIndex` (:issue:`37877`) - The ``inplace`` parameter of :meth:`Categorical.remove_unused_categories` is deprecated and will be removed in a future version (:issue:`37643`) diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index 38abc18b5f1cb..34ef041a8edbb 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -1,9 +1,10 @@ from datetime import datetime, timedelta from typing import Any, cast +import warnings import numpy as np -from pandas._libs import index as libindex +from pandas._libs import index as libindex, lib from pandas._libs.tslibs import BaseOffset, Period, Resolution, Tick from pandas._libs.tslibs.parsing import DateParseError, parse_time_string from pandas._typing import DtypeObj @@ -376,15 +377,25 @@ def asof_locs(self, where: Index, mask: np.ndarray) -> np.ndarray: return super().asof_locs(where, mask) @doc(Index.astype) - def astype(self, dtype, copy: bool = True, how="start"): + def astype(self, dtype, copy: bool = True, how=lib.no_default): dtype = pandas_dtype(dtype) + if how is not lib.no_default: + warnings.warn( + "The 'how' keyword in PeriodIndex.astype is deprecated and " + "will be removed in a future version. " + "Use index.to_timestamp(how=how) instead", + FutureWarning, + stacklevel=2, + ) + else: + how = "start" + if is_datetime64_any_dtype(dtype): # 'how' is index-specific, isn't part of the EA interface. tz = getattr(dtype, "tz", None) return self.to_timestamp(how=how).tz_localize(tz) - # TODO: should probably raise on `how` here, so we don't ignore it. return super().astype(dtype, copy=copy) @property diff --git a/pandas/tests/indexes/period/test_astype.py b/pandas/tests/indexes/period/test_astype.py index fa1617bdfaa52..0eed7c14969e7 100644 --- a/pandas/tests/indexes/period/test_astype.py +++ b/pandas/tests/indexes/period/test_astype.py @@ -144,13 +144,17 @@ def test_period_astype_to_timestamp(self): pi = PeriodIndex(["2011-01", "2011-02", "2011-03"], freq="M") exp = DatetimeIndex(["2011-01-01", "2011-02-01", "2011-03-01"], freq="MS") - res = pi.astype("datetime64[ns]") + with tm.assert_produces_warning(FutureWarning): + # how keyword deprecated + res = pi.astype("datetime64[ns]", how="start") tm.assert_index_equal(res, exp) assert res.freq == exp.freq exp = DatetimeIndex(["2011-01-31", "2011-02-28", "2011-03-31"]) exp = exp + Timedelta(1, "D") - Timedelta(1, "ns") - res = pi.astype("datetime64[ns]", how="end") + with tm.assert_produces_warning(FutureWarning): + # how keyword deprecated + res = pi.astype("datetime64[ns]", how="end") tm.assert_index_equal(res, exp) assert res.freq == exp.freq @@ -161,6 +165,8 @@ def test_period_astype_to_timestamp(self): exp = DatetimeIndex(["2011-01-31", "2011-02-28", "2011-03-31"], tz="US/Eastern") exp = exp + Timedelta(1, "D") - Timedelta(1, "ns") - res = pi.astype("datetime64[ns, US/Eastern]", how="end") + with tm.assert_produces_warning(FutureWarning): + # how keyword deprecated + res = pi.astype("datetime64[ns, US/Eastern]", how="end") tm.assert_index_equal(res, exp) assert res.freq == exp.freq From 7ab3153872d52be33656a8bee73d017116dcc467 Mon Sep 17 00:00:00 2001 From: Brock Date: Fri, 20 Nov 2020 14:35:27 -0800 Subject: [PATCH 2/2] GH refs --- doc/source/whatsnew/v1.2.0.rst | 2 +- pandas/core/indexes/period.py | 1 + pandas/tests/indexes/period/test_astype.py | 6 +++--- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/source/whatsnew/v1.2.0.rst b/doc/source/whatsnew/v1.2.0.rst index 17f220f1c2fae..c8623c047980d 100644 --- a/doc/source/whatsnew/v1.2.0.rst +++ b/doc/source/whatsnew/v1.2.0.rst @@ -476,7 +476,7 @@ Deprecations - :meth:`Categorical.is_dtype_equal` and :meth:`CategoricalIndex.is_dtype_equal` are deprecated, will be removed in a future version (:issue:`37545`) - :meth:`Series.slice_shift` and :meth:`DataFrame.slice_shift` are deprecated, use :meth:`Series.shift` or :meth:`DataFrame.shift` instead (:issue:`37601`) - Partial slicing on unordered :class:`DatetimeIndex` with keys, which are not in Index is deprecated and will be removed in a future version (:issue:`18531`) -- The ``how`` keyword in :meth:`PeriodIndex.astype` is deprecated and will be removed in a future version, use ``index.to_timestamp(how=how)`` instead (:issue:`???`) +- The ``how`` keyword in :meth:`PeriodIndex.astype` is deprecated and will be removed in a future version, use ``index.to_timestamp(how=how)`` instead (:issue:`37982`) - Deprecated :meth:`Index.asi8` for :class:`Index` subclasses other than :class:`DatetimeIndex`, :class:`TimedeltaIndex`, and :class:`PeriodIndex` (:issue:`37877`) - The ``inplace`` parameter of :meth:`Categorical.remove_unused_categories` is deprecated and will be removed in a future version (:issue:`37643`) diff --git a/pandas/core/indexes/period.py b/pandas/core/indexes/period.py index 34ef041a8edbb..28e3aa69f0bb5 100644 --- a/pandas/core/indexes/period.py +++ b/pandas/core/indexes/period.py @@ -381,6 +381,7 @@ def astype(self, dtype, copy: bool = True, how=lib.no_default): dtype = pandas_dtype(dtype) if how is not lib.no_default: + # GH#37982 warnings.warn( "The 'how' keyword in PeriodIndex.astype is deprecated and " "will be removed in a future version. " diff --git a/pandas/tests/indexes/period/test_astype.py b/pandas/tests/indexes/period/test_astype.py index 0eed7c14969e7..674d09c6a7a8c 100644 --- a/pandas/tests/indexes/period/test_astype.py +++ b/pandas/tests/indexes/period/test_astype.py @@ -145,7 +145,7 @@ def test_period_astype_to_timestamp(self): exp = DatetimeIndex(["2011-01-01", "2011-02-01", "2011-03-01"], freq="MS") with tm.assert_produces_warning(FutureWarning): - # how keyword deprecated + # how keyword deprecated GH#37982 res = pi.astype("datetime64[ns]", how="start") tm.assert_index_equal(res, exp) assert res.freq == exp.freq @@ -153,7 +153,7 @@ def test_period_astype_to_timestamp(self): exp = DatetimeIndex(["2011-01-31", "2011-02-28", "2011-03-31"]) exp = exp + Timedelta(1, "D") - Timedelta(1, "ns") with tm.assert_produces_warning(FutureWarning): - # how keyword deprecated + # how keyword deprecated GH#37982 res = pi.astype("datetime64[ns]", how="end") tm.assert_index_equal(res, exp) assert res.freq == exp.freq @@ -166,7 +166,7 @@ def test_period_astype_to_timestamp(self): exp = DatetimeIndex(["2011-01-31", "2011-02-28", "2011-03-31"], tz="US/Eastern") exp = exp + Timedelta(1, "D") - Timedelta(1, "ns") with tm.assert_produces_warning(FutureWarning): - # how keyword deprecated + # how keyword deprecated GH#37982 res = pi.astype("datetime64[ns, US/Eastern]", how="end") tm.assert_index_equal(res, exp) assert res.freq == exp.freq