From 58c1aac8d62cc79af603a2806b74352ce1bb3cf6 Mon Sep 17 00:00:00 2001 From: Brock Date: Tue, 7 Feb 2023 15:52:41 -0800 Subject: [PATCH 1/2] ENH: add unit, as_unit to dt accessor --- doc/source/reference/series.rst | 4 ++++ doc/source/whatsnew/v2.0.0.rst | 1 + pandas/core/arrays/datetimes.py | 5 ++++- pandas/core/arrays/timedeltas.py | 3 ++- pandas/core/indexes/accessors.py | 8 ++++++-- pandas/tests/series/accessors/test_cat_accessor.py | 1 + pandas/tests/series/accessors/test_dt_accessor.py | 2 ++ 7 files changed, 20 insertions(+), 4 deletions(-) diff --git a/doc/source/reference/series.rst b/doc/source/reference/series.rst index 659385c611ff0..5a43e5796d1d9 100644 --- a/doc/source/reference/series.rst +++ b/doc/source/reference/series.rst @@ -326,6 +326,7 @@ Datetime properties Series.dt.days_in_month Series.dt.tz Series.dt.freq + Series.dt.unit Datetime methods ^^^^^^^^^^^^^^^^ @@ -346,6 +347,7 @@ Datetime methods Series.dt.ceil Series.dt.month_name Series.dt.day_name + Series.dt.as_unit Period properties ^^^^^^^^^^^^^^^^^ @@ -370,6 +372,7 @@ Timedelta properties Series.dt.microseconds Series.dt.nanoseconds Series.dt.components + Series.dt.unit Timedelta methods ^^^^^^^^^^^^^^^^^ @@ -380,6 +383,7 @@ Timedelta methods Series.dt.to_pytimedelta Series.dt.total_seconds + Series.dt.as_unit .. _api.series.str: diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 7d028935ad175..55fd2266afd80 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -289,6 +289,7 @@ Other enhancements - Improved error message in :func:`to_datetime` for non-ISO8601 formats, informing users about the position of the first error (:issue:`50361`) - Improved error message when trying to align :class:`DataFrame` objects (for example, in :func:`DataFrame.compare`) to clarify that "identically labelled" refers to both index and columns (:issue:`50083`) - Added :meth:`DatetimeIndex.as_unit` and :meth:`TimedeltaIndex.as_unit` to convert to different resolutions; supported resolutions are "s", "ms", "us", and "ns" (:issue:`50616`) +- Added :meth:`Series.dt.unit` and :meth:`Series.dt.as_unit` to convert to different resolutions; supported resolutions are "s", "ms", "us", and "ns" (:issue:`50616`) - Added new argument ``dtype`` to :func:`read_sql` to be consistent with :func:`read_sql_query` (:issue:`50797`) - diff --git a/pandas/core/arrays/datetimes.py b/pandas/core/arrays/datetimes.py index 1bf43f61a67a7..d2154265d5cb0 100644 --- a/pandas/core/arrays/datetimes.py +++ b/pandas/core/arrays/datetimes.py @@ -228,7 +228,9 @@ def _scalar_type(self) -> type[Timestamp]: "nanosecond", ] _other_ops: list[str] = ["date", "time", "timetz"] - _datetimelike_ops: list[str] = _field_ops + _object_ops + _bool_ops + _other_ops + _datetimelike_ops: list[str] = ( + _field_ops + _object_ops + _bool_ops + _other_ops + ["unit"] + ) _datetimelike_methods: list[str] = [ "to_period", "tz_localize", @@ -240,6 +242,7 @@ def _scalar_type(self) -> type[Timestamp]: "ceil", "month_name", "day_name", + "as_unit", ] # ndim is inherited from ExtensionArray, must exist to ensure diff --git a/pandas/core/arrays/timedeltas.py b/pandas/core/arrays/timedeltas.py index 861c9712cd2ae..65eaf83c48bb8 100644 --- a/pandas/core/arrays/timedeltas.py +++ b/pandas/core/arrays/timedeltas.py @@ -137,13 +137,14 @@ def _scalar_type(self) -> type[Timedelta]: _bool_ops: list[str] = [] _object_ops: list[str] = ["freq"] _field_ops: list[str] = ["days", "seconds", "microseconds", "nanoseconds"] - _datetimelike_ops: list[str] = _field_ops + _object_ops + _bool_ops + _datetimelike_ops: list[str] = _field_ops + _object_ops + _bool_ops + ["unit"] _datetimelike_methods: list[str] = [ "to_pytimedelta", "total_seconds", "round", "floor", "ceil", + "as_unit", ] # Note: ndim must be defined to ensure NaT.__richcmp__(TimedeltaArray) diff --git a/pandas/core/indexes/accessors.py b/pandas/core/indexes/accessors.py index 9e4680d2205b9..2c22d7412c6b7 100644 --- a/pandas/core/indexes/accessors.py +++ b/pandas/core/indexes/accessors.py @@ -140,10 +140,14 @@ def _delegate_method(self, name, *args, **kwargs): @delegate_names( - delegate=DatetimeArray, accessors=DatetimeArray._datetimelike_ops, typ="property" + delegate=DatetimeArray, + accessors=DatetimeArray._datetimelike_ops + ["unit"], + typ="property", ) @delegate_names( - delegate=DatetimeArray, accessors=DatetimeArray._datetimelike_methods, typ="method" + delegate=DatetimeArray, + accessors=DatetimeArray._datetimelike_methods + ["as_unit"], + typ="method", ) class DatetimeProperties(Properties): """ diff --git a/pandas/tests/series/accessors/test_cat_accessor.py b/pandas/tests/series/accessors/test_cat_accessor.py index 9266afc89fa19..c999a3efee31f 100644 --- a/pandas/tests/series/accessors/test_cat_accessor.py +++ b/pandas/tests/series/accessors/test_cat_accessor.py @@ -167,6 +167,7 @@ def test_dt_accessor_api_for_categorical(self, idx): ("floor", ("D",), {}), ("ceil", ("D",), {}), ("asfreq", ("D",), {}), + ("as_unit", ("s"), {}), ] if idx.dtype == "M8[ns]": # exclude dt64tz since that is already localized and would raise diff --git a/pandas/tests/series/accessors/test_dt_accessor.py b/pandas/tests/series/accessors/test_dt_accessor.py index 1914bdae07e4b..a7e3cd43d1a6e 100644 --- a/pandas/tests/series/accessors/test_dt_accessor.py +++ b/pandas/tests/series/accessors/test_dt_accessor.py @@ -55,6 +55,7 @@ "day_name", "month_name", "isocalendar", + "as_unit", ] ok_for_td = TimedeltaArray._datetimelike_ops ok_for_td_methods = [ @@ -64,6 +65,7 @@ "round", "floor", "ceil", + "as_unit", ] From d911c91e9a24e5e93377e87c2078ae6d4c0ab479 Mon Sep 17 00:00:00 2001 From: Brock Date: Tue, 7 Feb 2023 15:53:47 -0800 Subject: [PATCH 2/2] GH ref --- doc/source/whatsnew/v2.0.0.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/source/whatsnew/v2.0.0.rst b/doc/source/whatsnew/v2.0.0.rst index 55fd2266afd80..2bc098c5384f0 100644 --- a/doc/source/whatsnew/v2.0.0.rst +++ b/doc/source/whatsnew/v2.0.0.rst @@ -289,7 +289,7 @@ Other enhancements - Improved error message in :func:`to_datetime` for non-ISO8601 formats, informing users about the position of the first error (:issue:`50361`) - Improved error message when trying to align :class:`DataFrame` objects (for example, in :func:`DataFrame.compare`) to clarify that "identically labelled" refers to both index and columns (:issue:`50083`) - Added :meth:`DatetimeIndex.as_unit` and :meth:`TimedeltaIndex.as_unit` to convert to different resolutions; supported resolutions are "s", "ms", "us", and "ns" (:issue:`50616`) -- Added :meth:`Series.dt.unit` and :meth:`Series.dt.as_unit` to convert to different resolutions; supported resolutions are "s", "ms", "us", and "ns" (:issue:`50616`) +- Added :meth:`Series.dt.unit` and :meth:`Series.dt.as_unit` to convert to different resolutions; supported resolutions are "s", "ms", "us", and "ns" (:issue:`51223`) - Added new argument ``dtype`` to :func:`read_sql` to be consistent with :func:`read_sql_query` (:issue:`50797`) -