From f90bd922dd6e986badd0e8c22baa60ace9cab07f Mon Sep 17 00:00:00 2001 From: MarcoGorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Thu, 5 Oct 2023 12:47:02 +0100 Subject: [PATCH 1/7] add datetime accessor --- .../dataframe_api/column_object.py | 105 ++++++++++++++++++ 1 file changed, 105 insertions(+) diff --git a/spec/API_specification/dataframe_api/column_object.py b/spec/API_specification/dataframe_api/column_object.py index ff4d7ba3..81693cf0 100644 --- a/spec/API_specification/dataframe_api/column_object.py +++ b/spec/API_specification/dataframe_api/column_object.py @@ -2,6 +2,8 @@ from typing import Any,NoReturn, TYPE_CHECKING, Literal, Generic +from datetime import timedelta + if TYPE_CHECKING: from ._types import NullType, Scalar, DType, Namespace @@ -763,3 +765,106 @@ def rename(self, name: str) -> Column: New column - this does not operate in-place. """ ... + + @property + def dt(self) -> DatetimeAccessor: + """ + Return accessor with functions which work on temporal dtypes. + """ + ... + +class DatetimeAccessor: + """ + Method which operate on temporal Columns. + """ + + def year(self) -> Column: + """ + Return 'year' component of each element. + + For example, return 1981 for 1981-01-02T12:34:56.123456. + """ + + def month(self) -> Column: + """ + Return 'month' component of each element. + + For example, return 1 for 1981-01-02T12:34:56.123456. + """ + + def day(self) -> Column: + """ + Return 'day' component of each element. + + For example, return 2 for 1981-01-02T12:34:56.123456. + """ + + def hour(self) -> Column: + """ + Return 'hour' component of each element. + + For example, return 12 for 1981-01-02T12:34:56.123456. + """ + + def minute(self) -> Column: + """ + Return 'minute' component of each element. + + For example, return 34 for 1981-01-02T12:34:56.123456. + """ + + def second(self) -> Column: + """ + Return 'second' component of each element. + + For example, return 56 for 1981-01-02T12:34:56.123456. + """ + + def microsecond(self) -> Column: + """ + Return number of microseconds since last second, for each element. + + For example, return 123456 for 1981-01-02T12:34:56.123456. + """ + + def floor(self, frequency: timedelta) -> Column: + """ + Return floor of each element according to the specified frequency. + + Flooring is done according to local time. For example, + for a ``Datetime('us', 'Europe/London')`` column, + ``"2020-10-25T00:30:00 BST"`` floored by ``"1day"`` gives + ``"2020-10-25T00:00:00 BST"``. + + Behaviours in the face of ambiguous and non-existent times are + currently unspecified and may vary across implementations. + + Flooring by non-fixed durations (e.g. calendar month) are not supported. + Note that flooring by ``timedelta(days=1)`` is equivalent to flooring + by ``timedelta(hours=24)``. + + Parameters + ---------- + freq : timedelta + Frequency to floor by. + """ + + def iso_weekday(self) -> Column: + """ + Return ISO weekday for each element. + + Note that Monday=1, ..., Sunday=7. + """ + + def timestamp(self) -> Column: + """ + Return number of units since UNIX epoch (1970-01-01). + + Units depend on the dtype of the column: + + - For a :class:`Date` column, ``1970-01-02`` should return `1`; + - For a :class:`Datetime('ms', '*')` column, ``1970-01-02`` + should return `86_400_000`; + - For a :class:`Datetime('us', '*')` column, ``1970-01-02`` + should return `86_400_000_000`; + """ From b7ffcaca20076b1fd954400a363c05b7db02ee5c Mon Sep 17 00:00:00 2001 From: MarcoGorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Sat, 7 Oct 2023 13:05:22 +0300 Subject: [PATCH 2/7] remove floor --- .../dataframe_api/column_object.py | 34 ------------------- 1 file changed, 34 deletions(-) diff --git a/spec/API_specification/dataframe_api/column_object.py b/spec/API_specification/dataframe_api/column_object.py index 81693cf0..98f58410 100644 --- a/spec/API_specification/dataframe_api/column_object.py +++ b/spec/API_specification/dataframe_api/column_object.py @@ -827,28 +827,6 @@ def microsecond(self) -> Column: For example, return 123456 for 1981-01-02T12:34:56.123456. """ - def floor(self, frequency: timedelta) -> Column: - """ - Return floor of each element according to the specified frequency. - - Flooring is done according to local time. For example, - for a ``Datetime('us', 'Europe/London')`` column, - ``"2020-10-25T00:30:00 BST"`` floored by ``"1day"`` gives - ``"2020-10-25T00:00:00 BST"``. - - Behaviours in the face of ambiguous and non-existent times are - currently unspecified and may vary across implementations. - - Flooring by non-fixed durations (e.g. calendar month) are not supported. - Note that flooring by ``timedelta(days=1)`` is equivalent to flooring - by ``timedelta(hours=24)``. - - Parameters - ---------- - freq : timedelta - Frequency to floor by. - """ - def iso_weekday(self) -> Column: """ Return ISO weekday for each element. @@ -856,15 +834,3 @@ def iso_weekday(self) -> Column: Note that Monday=1, ..., Sunday=7. """ - def timestamp(self) -> Column: - """ - Return number of units since UNIX epoch (1970-01-01). - - Units depend on the dtype of the column: - - - For a :class:`Date` column, ``1970-01-02`` should return `1`; - - For a :class:`Datetime('ms', '*')` column, ``1970-01-02`` - should return `86_400_000`; - - For a :class:`Datetime('us', '*')` column, ``1970-01-02`` - should return `86_400_000_000`; - """ From 41017d9d4b52e1b9eeacd5d608f23076f9c2bb14 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Sat, 7 Oct 2023 13:46:24 +0300 Subject: [PATCH 3/7] fixup --- spec/API_specification/column_object.rst | 2 ++ spec/API_specification/dataframe_api/__init__.py | 1 + spec/API_specification/dataframe_api/column_object.py | 4 ++-- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/spec/API_specification/column_object.rst b/spec/API_specification/column_object.rst index 3201b500..5ff16633 100644 --- a/spec/API_specification/column_object.rst +++ b/spec/API_specification/column_object.rst @@ -10,3 +10,5 @@ behavior. .. currentmodule:: dataframe_api .. autoclass:: Column + +.. autoclass:: DatetimeAccessor diff --git a/spec/API_specification/dataframe_api/__init__.py b/spec/API_specification/dataframe_api/__init__.py index 4829eb48..a4218650 100644 --- a/spec/API_specification/dataframe_api/__init__.py +++ b/spec/API_specification/dataframe_api/__init__.py @@ -40,6 +40,7 @@ "Duration", "String", "is_dtype", + "DatetimeAccessor", ] diff --git a/spec/API_specification/dataframe_api/column_object.py b/spec/API_specification/dataframe_api/column_object.py index 98f58410..61710865 100644 --- a/spec/API_specification/dataframe_api/column_object.py +++ b/spec/API_specification/dataframe_api/column_object.py @@ -8,7 +8,7 @@ from ._types import NullType, Scalar, DType, Namespace -__all__ = ['Column'] +__all__ = ['Column', 'DatetimeAccessor'] class Column: @@ -767,7 +767,7 @@ def rename(self, name: str) -> Column: ... @property - def dt(self) -> DatetimeAccessor: + def dt(self) -> "DatetimeAccessor": """ Return accessor with functions which work on temporal dtypes. """ From f231d1f774443b8fb1cdfefd4309c760be8f1b83 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Tue, 17 Oct 2023 09:45:26 +0300 Subject: [PATCH 4/7] remove .dt accessor, specify integerness of return columns --- .../dataframe_api/column_object.py | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/spec/API_specification/dataframe_api/column_object.py b/spec/API_specification/dataframe_api/column_object.py index 61710865..8c3032c9 100644 --- a/spec/API_specification/dataframe_api/column_object.py +++ b/spec/API_specification/dataframe_api/column_object.py @@ -766,71 +766,76 @@ def rename(self, name: str) -> Column: """ ... - @property - def dt(self) -> "DatetimeAccessor": - """ - Return accessor with functions which work on temporal dtypes. - """ - ... - -class DatetimeAccessor: - """ - Method which operate on temporal Columns. - """ def year(self) -> Column: """ - Return 'year' component of each element. + Return 'year' component of each element of `Date` and `Datetime` columns. For example, return 1981 for 1981-01-02T12:34:56.123456. + + Return column should be of (signed) integer dtype. """ def month(self) -> Column: """ - Return 'month' component of each element. + Return 'month' component of each element of `Date` and `Datetime` columns. For example, return 1 for 1981-01-02T12:34:56.123456. + + Return column should be of integer dtype (signed or unsigned). """ def day(self) -> Column: """ - Return 'day' component of each element. + Return 'day' component of each element of `Date` and `Datetime` columns. For example, return 2 for 1981-01-02T12:34:56.123456. + + Return column should be of integer dtype (signed or unsigned). """ def hour(self) -> Column: """ - Return 'hour' component of each element. + Return 'hour' component of each element of `Date` and `Datetime` columns. For example, return 12 for 1981-01-02T12:34:56.123456. + + Return column should be of integer dtype (signed or unsigned). """ def minute(self) -> Column: """ - Return 'minute' component of each element. + Return 'minute' component of each element of `Date` and `Datetime` columns. For example, return 34 for 1981-01-02T12:34:56.123456. + + Return column should be of integer dtype (signed or unsigned). """ def second(self) -> Column: """ - Return 'second' component of each element. + Return 'second' component of each element of `Date` and `Datetime` columns. For example, return 56 for 1981-01-02T12:34:56.123456. + + Return column should be of integer dtype (signed or unsigned). """ def microsecond(self) -> Column: """ - Return number of microseconds since last second, for each element. + Return number of microseconds since last second, for each element of `Date` and `Datetime` columns. For example, return 123456 for 1981-01-02T12:34:56.123456. + + Return column should be of integer dtype (signed or unsigned). """ def iso_weekday(self) -> Column: """ - Return ISO weekday for each element. + Return ISO weekday for each element of `Date` and `Datetime` columns. Note that Monday=1, ..., Sunday=7. + + Return column should be of integer dtype (signed or unsigned). """ From 987d12e2b8a8e0a287118dc3f467b9b3fe1c2bde Mon Sep 17 00:00:00 2001 From: MarcoGorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Thu, 26 Oct 2023 10:57:18 +0100 Subject: [PATCH 5/7] fixup --- .../dataframe_api/column_object.py | 69 +++++++++++++++---- .../dataframe_api/dataframe_object.py | 3 + 2 files changed, 59 insertions(+), 13 deletions(-) diff --git a/spec/API_specification/dataframe_api/column_object.py b/spec/API_specification/dataframe_api/column_object.py index f0d8d710..638381eb 100644 --- a/spec/API_specification/dataframe_api/column_object.py +++ b/spec/API_specification/dataframe_api/column_object.py @@ -2,14 +2,12 @@ from typing import Any,NoReturn, TYPE_CHECKING, Literal, Protocol -from datetime import timedelta - if TYPE_CHECKING: from .typing import NullType, Scalar, DType, Namespace from typing_extensions import Self -__all__ = ['Column', 'DatetimeAccessor'] +__all__ = ['Column'] class Column(Protocol): @@ -34,8 +32,8 @@ def __column_namespace__(self) -> Namespace: attribute. It may contain other public names as well, but it is recommended to only include those names that are part of the specification. - """ + ... @property def column(self) -> Any: @@ -54,6 +52,7 @@ def __len__(self) -> int: """ Return the number of rows. """ + ... def __iter__(self) -> NoReturn: """ @@ -68,10 +67,11 @@ def __iter__(self) -> NoReturn: raise NotImplementedError("'__iter__' is intentionally not implemented.") @property - def dtype(self) -> Any: + def dtype(self) -> DType: """ Return data type of column. """ + ... def get_rows(self, indices: Self) -> Self: """ @@ -215,6 +215,7 @@ def __eq__(self, other: Self | Scalar) -> Self: # type: ignore[override] ------- Column """ + ... def __ne__(self, other: Self | Scalar) -> Self: # type: ignore[override] """ @@ -233,6 +234,7 @@ def __ne__(self, other: Self | Scalar) -> Self: # type: ignore[override] ------- Column """ + ... def __ge__(self, other: Self | Scalar) -> Self: """ @@ -249,6 +251,7 @@ def __ge__(self, other: Self | Scalar) -> Self: ------- Column """ + ... def __gt__(self, other: Self | Scalar) -> Self: """ @@ -265,6 +268,7 @@ def __gt__(self, other: Self | Scalar) -> Self: ------- Column """ + ... def __le__(self, other: Self | Scalar) -> Self: """ @@ -281,6 +285,7 @@ def __le__(self, other: Self | Scalar) -> Self: ------- Column """ + ... def __lt__(self, other: Self | Scalar) -> Self: """ @@ -297,6 +302,7 @@ def __lt__(self, other: Self | Scalar) -> Self: ------- Column """ + ... def __and__(self, other: Self | bool) -> Self: """ @@ -318,6 +324,7 @@ def __and__(self, other: Self | bool) -> Self: ValueError If `self` or `other` is not boolean. """ + ... def __or__(self, other: Self | bool) -> Self: """ @@ -339,6 +346,7 @@ def __or__(self, other: Self | bool) -> Self: ValueError If `self` or `other` is not boolean. """ + ... def __add__(self, other: Self | Scalar) -> Self: """ @@ -355,6 +363,7 @@ def __add__(self, other: Self | Scalar) -> Self: ------- Column """ + ... def __sub__(self, other: Self | Scalar) -> Self: """ @@ -371,6 +380,7 @@ def __sub__(self, other: Self | Scalar) -> Self: ------- Column """ + ... def __mul__(self, other: Self | Scalar) -> Self: """ @@ -387,6 +397,7 @@ def __mul__(self, other: Self | Scalar) -> Self: ------- Column """ + ... def __truediv__(self, other: Self | Scalar) -> Self: """ @@ -403,6 +414,7 @@ def __truediv__(self, other: Self | Scalar) -> Self: ------- Column """ + ... def __floordiv__(self, other: Self | Scalar) -> Self: """ @@ -419,6 +431,7 @@ def __floordiv__(self, other: Self | Scalar) -> Self: ------- Column """ + ... def __pow__(self, other: Self | Scalar) -> Self: """ @@ -439,6 +452,7 @@ def __pow__(self, other: Self | Scalar) -> Self: ------- Column """ + ... def __mod__(self, other: Self | Scalar) -> Self: """ @@ -455,6 +469,7 @@ def __mod__(self, other: Self | Scalar) -> Self: ------- Column """ + ... def __divmod__(self, other: Self | Scalar) -> tuple[Column, Column]: """ @@ -471,6 +486,7 @@ def __divmod__(self, other: Self | Scalar) -> tuple[Column, Column]: ------- Column """ + ... def __radd__(self, other: Self | Scalar) -> Self: ... @@ -500,6 +516,7 @@ def __invert__(self) -> Self: ValueError If any of the Column's columns is not boolean. """ + ... def any(self, *, skip_nulls: bool = True) -> bool | NullType: """ @@ -510,6 +527,7 @@ def any(self, *, skip_nulls: bool = True) -> bool | NullType: ValueError If column is not boolean. """ + ... def all(self, *, skip_nulls: bool = True) -> bool | NullType: """ @@ -520,18 +538,21 @@ def all(self, *, skip_nulls: bool = True) -> bool | NullType: ValueError If column is not boolean. """ + ... def min(self, *, skip_nulls: bool = True) -> Scalar | NullType: """ Reduction returns a scalar. Any data type that supports comparisons must be supported. The returned value has the same dtype as the column. """ + ... def max(self, *, skip_nulls: bool = True) -> Scalar | NullType: """ Reduction returns a scalar. Any data type that supports comparisons must be supported. The returned value has the same dtype as the column. """ + ... def sum(self, *, skip_nulls: bool = True) -> Scalar | NullType: """ @@ -539,12 +560,14 @@ def sum(self, *, skip_nulls: bool = True) -> Scalar | NullType: datetime data types. The returned value has the same dtype as the column. """ + ... def prod(self, *, skip_nulls: bool = True) -> Scalar | NullType: """ Reduction returns a scalar. Must be supported for numerical data types. The returned value has the same dtype as the column. """ + ... def median(self, *, skip_nulls: bool = True) -> Scalar | NullType: """ @@ -553,6 +576,7 @@ def median(self, *, skip_nulls: bool = True) -> Scalar | NullType: datetime (with the appropriate timedelta format string) for datetime dtypes. """ + ... def mean(self, *, skip_nulls: bool = True) -> Scalar | NullType: """ @@ -561,6 +585,7 @@ def mean(self, *, skip_nulls: bool = True) -> Scalar | NullType: datetime (with the appropriate timedelta format string) for datetime dtypes. """ + ... def std(self, *, correction: int | float = 1, skip_nulls: bool = True) -> Scalar | NullType: """ @@ -587,6 +612,7 @@ def std(self, *, correction: int | float = 1, skip_nulls: bool = True) -> Scalar skip_nulls Whether to skip null values. """ + ... def var(self, *, correction: int | float = 1, skip_nulls: bool = True) -> Scalar | NullType: """ @@ -604,18 +630,21 @@ def var(self, *, correction: int | float = 1, skip_nulls: bool = True) -> Scalar skip_nulls Whether to skip null values. """ + ... def cumulative_max(self) -> Self: """ Reduction returns a Column. Any data type that supports comparisons must be supported. The returned value has the same dtype as the column. """ + ... def cumulative_min(self) -> Self: """ Reduction returns a Column. Any data type that supports comparisons must be supported. The returned value has the same dtype as the column. """ + ... def cumulative_sum(self) -> Self: """ @@ -623,6 +652,7 @@ def cumulative_sum(self) -> Self: datetime data types. The returned value has the same dtype as the column. """ + ... def cumulative_prod(self) -> Self: """ @@ -630,6 +660,7 @@ def cumulative_prod(self) -> Self: datetime data types. The returned value has the same dtype as the column. """ + ... def is_null(self) -> Self: """ @@ -649,6 +680,7 @@ def is_null(self) -> Self: May optionally include 'NaT' values (if present in an implementation), but note that the Standard makes no guarantees about them. """ + ... def is_nan(self) -> Self: """ @@ -668,6 +700,7 @@ def is_nan(self) -> Self: Does *not* include 'missing' or 'null' entries. In particular, does not check for `np.timedelta64('NaT')`. """ + ... def is_in(self, values: Self) -> Self: """ @@ -686,6 +719,7 @@ def is_in(self, values: Self) -> Self: ------- Column """ + ... def unique_indices(self, *, skip_nulls: bool = True) -> Self: """ @@ -768,6 +802,7 @@ def to_array(self) -> Any: understanding that consuming libraries would then use the ``array-api-compat`` package to convert it to a Standard-compliant array. """ + ... def rename(self, name: str) -> Self: """ @@ -786,7 +821,7 @@ def rename(self, name: str) -> Self: ... - def year(self) -> Column: + def year(self) -> Self: """ Return 'year' component of each element of `Date` and `Datetime` columns. @@ -794,8 +829,9 @@ def year(self) -> Column: Return column should be of (signed) integer dtype. """ + ... - def month(self) -> Column: + def month(self) -> Self: """ Return 'month' component of each element of `Date` and `Datetime` columns. @@ -803,8 +839,9 @@ def month(self) -> Column: Return column should be of integer dtype (signed or unsigned). """ + ... - def day(self) -> Column: + def day(self) -> Self: """ Return 'day' component of each element of `Date` and `Datetime` columns. @@ -812,8 +849,9 @@ def day(self) -> Column: Return column should be of integer dtype (signed or unsigned). """ + ... - def hour(self) -> Column: + def hour(self) -> Self: """ Return 'hour' component of each element of `Date` and `Datetime` columns. @@ -821,8 +859,9 @@ def hour(self) -> Column: Return column should be of integer dtype (signed or unsigned). """ + ... - def minute(self) -> Column: + def minute(self) -> Self: """ Return 'minute' component of each element of `Date` and `Datetime` columns. @@ -830,8 +869,9 @@ def minute(self) -> Column: Return column should be of integer dtype (signed or unsigned). """ + ... - def second(self) -> Column: + def second(self) -> Self: """ Return 'second' component of each element of `Date` and `Datetime` columns. @@ -839,8 +879,9 @@ def second(self) -> Column: Return column should be of integer dtype (signed or unsigned). """ + ... - def microsecond(self) -> Column: + def microsecond(self) -> Self: """ Return number of microseconds since last second, for each element of `Date` and `Datetime` columns. @@ -848,8 +889,9 @@ def microsecond(self) -> Column: Return column should be of integer dtype (signed or unsigned). """ + ... - def iso_weekday(self) -> Column: + def iso_weekday(self) -> Self: """ Return ISO weekday for each element of `Date` and `Datetime` columns. @@ -857,4 +899,5 @@ def iso_weekday(self) -> Column: Return column should be of integer dtype (signed or unsigned). """ + ... diff --git a/spec/API_specification/dataframe_api/dataframe_object.py b/spec/API_specification/dataframe_api/dataframe_object.py index c577a853..7d4d5c41 100644 --- a/spec/API_specification/dataframe_api/dataframe_object.py +++ b/spec/API_specification/dataframe_api/dataframe_object.py @@ -64,6 +64,7 @@ def shape(self) -> tuple[int, int]: """ Return number of rows and number of columns. """ + ... def group_by(self, *keys: str) -> GroupBy: """ @@ -463,6 +464,7 @@ def __and__(self, other: bool) -> Self: ValueError If `self` or `other` is not boolean. """ + ... def __or__(self, other: bool) -> Self: """ @@ -483,6 +485,7 @@ def __or__(self, other: bool) -> Self: ValueError If `self` or `other` is not boolean. """ + ... def __add__(self, other: Scalar) -> Self: """ From a43ad4a4f37db15b6da66babfe6af5b058fb7a74 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Sat, 7 Oct 2023 19:28:46 +0300 Subject: [PATCH 6/7] add dt.floor --- .../dataframe_api/column_object.py | 35 +++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/spec/API_specification/dataframe_api/column_object.py b/spec/API_specification/dataframe_api/column_object.py index 638381eb..8355266b 100644 --- a/spec/API_specification/dataframe_api/column_object.py +++ b/spec/API_specification/dataframe_api/column_object.py @@ -901,3 +901,38 @@ def iso_weekday(self) -> Self: """ ... + def floor(self, frequency: str) -> Column: + """ + Return floor of each element according to the specified frequency. + + Flooring is done according to local time. For example, + for a ``Datetime('us', 'Europe/London')`` column, + ``"2020-10-25T00:30:00 BST"`` floored by ``"1day"`` gives + ``"2020-10-25T00:00:00 BST"``. + Behaviours in the face of ambiguous and non-existent times are + currently unspecified and may vary across implementations. + + Flooring by non-fixed durations (e.g. calendar month) are not supported. + Note that flooring by ``timedelta(days=1)`` is equivalent to flooring + by ``timedelta(hours=24)``. + + Parameters + ---------- + freq : str + Frequency to floor by. Can be constructed using the following string + language: + + - "1day" + - "1hour" + - "1minute" + - "1second" + - "1millisecond" + - "1microsecond" + + Examples + -------- + Roll each datetime back to the beginning of the day: + + >>> column: Column + >>> column.dt.floor("1day") + """ From 6b04f771b231f4d642bfe0555ba0dfa3c1cea810 Mon Sep 17 00:00:00 2001 From: MarcoGorelli <33491632+MarcoGorelli@users.noreply.github.com> Date: Thu, 26 Oct 2023 11:10:42 +0100 Subject: [PATCH 7/7] clarify --- spec/API_specification/column_object.rst | 2 -- .../dataframe_api/column_object.py | 23 ++++++++++++++----- 2 files changed, 17 insertions(+), 8 deletions(-) diff --git a/spec/API_specification/column_object.rst b/spec/API_specification/column_object.rst index 5ff16633..3201b500 100644 --- a/spec/API_specification/column_object.rst +++ b/spec/API_specification/column_object.rst @@ -10,5 +10,3 @@ behavior. .. currentmodule:: dataframe_api .. autoclass:: Column - -.. autoclass:: DatetimeAccessor diff --git a/spec/API_specification/dataframe_api/column_object.py b/spec/API_specification/dataframe_api/column_object.py index 8355266b..632580f5 100644 --- a/spec/API_specification/dataframe_api/column_object.py +++ b/spec/API_specification/dataframe_api/column_object.py @@ -901,7 +901,7 @@ def iso_weekday(self) -> Self: """ ... - def floor(self, frequency: str) -> Column: + def floor(self, frequency: str) -> Self: """ Return floor of each element according to the specified frequency. @@ -922,12 +922,22 @@ def floor(self, frequency: str) -> Column: Frequency to floor by. Can be constructed using the following string language: + - "day(s)" + - "hour(s)" + - "minute(s)" + - "second(s)" + - "millisecond(s)" + - "microsecond(s)" + + where ```` is a positive integer and the trailing (s) is + optional. + Multiple frequencies can be specified, separated by blank spaces. + + Examples of valid inputs are: + - "1day" - - "1hour" - - "1minute" - - "1second" - - "1millisecond" - - "1microsecond" + - "1day 1hour" + - "1day 2hours 3minutes 4seconds 5milliseconds 6microseconds" Examples -------- @@ -936,3 +946,4 @@ def floor(self, frequency: str) -> Column: >>> column: Column >>> column.dt.floor("1day") """ + ...