Skip to content

Commit

Permalink
Implemented bindings for ceil timestamp operation (#9141)
Browse files Browse the repository at this point in the history
Closes #8682. Added python bindings for `ceil` operation implemented in #8942.

Authors:
  - https://github.com/shaneding

Approvers:
  - Ashwin Srinath (https://github.com/shwina)
  - https://github.com/brandon-b-miller

URL: #9141
  • Loading branch information
shaneding authored Sep 4, 2021
1 parent 0d9f363 commit 8d602b7
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 0 deletions.
11 changes: 11 additions & 0 deletions python/cudf/cudf/_lib/cpp/datetime.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ cdef extern from "cudf/datetime.hpp" namespace "cudf::datetime" nogil:
cdef unique_ptr[column] extract_hour(const column_view& column) except +
cdef unique_ptr[column] extract_minute(const column_view& column) except +
cdef unique_ptr[column] extract_second(const column_view& column) except +
cdef unique_ptr[column] ceil_day(const column_view& column) except +
cdef unique_ptr[column] ceil_hour(const column_view& column) except +
cdef unique_ptr[column] ceil_minute(const column_view& column) except +
cdef unique_ptr[column] ceil_second(const column_view& column) except +
cdef unique_ptr[column] ceil_millisecond(
const column_view& column
) except +
cdef unique_ptr[column] ceil_microsecond(
const column_view& column
) except +
cdef unique_ptr[column] ceil_nanosecond(const column_view& column) except +
cdef unique_ptr[column] add_calendrical_months(
const column_view& timestamps,
const column_view& months
Expand Down
27 changes: 27 additions & 0 deletions python/cudf/cudf/_lib/datetime.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,33 @@ def extract_datetime_component(Column col, object field):
return result


def ceil_datetime(Column col, object field):
cdef unique_ptr[column] c_result
cdef column_view col_view = col.view()

with nogil:
# https://pandas.pydata.org/pandas-docs/version/0.25.0/reference/api/pandas.Timedelta.resolution.html
if field == "D":
c_result = move(libcudf_datetime.ceil_day(col_view))
elif field == "H":
c_result = move(libcudf_datetime.ceil_hour(col_view))
elif field == "T":
c_result = move(libcudf_datetime.ceil_minute(col_view))
elif field == "S":
c_result = move(libcudf_datetime.ceil_second(col_view))
elif field == "L":
c_result = move(libcudf_datetime.ceil_millisecond(col_view))
elif field == "U":
c_result = move(libcudf_datetime.ceil_microsecond(col_view))
elif field == "N":
c_result = move(libcudf_datetime.ceil_nanosecond(col_view))
else:
raise ValueError(f"Invalid resolution: '{field}'")

result = Column.from_unique_ptr(move(c_result))
return result


def is_leap_year(Column col):
"""Returns a boolean indicator whether the year of the date is a leap year
"""
Expand Down
3 changes: 3 additions & 0 deletions python/cudf/cudf/core/column/datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,9 @@ def values(self):
def get_dt_field(self, field: str) -> ColumnBase:
return libcudf.datetime.extract_datetime_component(self, field)

def ceil(self, field: str) -> ColumnBase:
return libcudf.datetime.ceil_datetime(self, field)

def normalize_binop_value(self, other: DatetimeLikeScalar) -> ScalarLike:
if isinstance(other, cudf.Scalar):
return other
Expand Down
7 changes: 7 additions & 0 deletions python/cudf/cudf/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -5740,6 +5740,13 @@ def _get_dt_field(self, field):
data=out_column, index=self.series._index, name=self.series.name
)

def ceil(self, field):
out_column = self.series._column.ceil(field)

return Series(
data=out_column, index=self.series._index, name=self.series.name
)

def strftime(self, date_format, *args, **kwargs):
"""
Convert to Series using specified ``date_format``.
Expand Down
29 changes: 29 additions & 0 deletions python/cudf/cudf/tests/test_datetime.py
Original file line number Diff line number Diff line change
Expand Up @@ -1551,3 +1551,32 @@ def test_error_values():
match="DateTime Arrays is not yet implemented in cudf",
):
s.values


@pytest.mark.parametrize(
"data",
[
(
[
"2020-05-31 08:00:00",
"1999-12-31 18:40:10",
"2000-12-31 04:00:05",
"1900-02-28 07:00:06",
"1800-03-14 07:30:20",
"2100-03-14 07:30:20",
"1970-01-01 00:00:09",
"1969-12-31 12:59:10",
]
)
],
)
@pytest.mark.parametrize("time_type", DATETIME_TYPES)
@pytest.mark.parametrize("resolution", ["D", "H", "T", "S", "L", "U", "N"])
def test_ceil(data, time_type, resolution):

ps = pd.Series(data, dtype=time_type)
gs = cudf.from_pandas(ps)

expect = ps.dt.ceil(resolution)
got = gs.dt.ceil(resolution)
assert_eq(expect, got)

0 comments on commit 8d602b7

Please sign in to comment.