diff --git a/bigframes/operations/datetimes.py b/bigframes/operations/datetimes.py index 56320e7cc6..14bf10f463 100644 --- a/bigframes/operations/datetimes.py +++ b/bigframes/operations/datetimes.py @@ -49,10 +49,18 @@ def day(self) -> series.Series: def dayofweek(self) -> series.Series: return self._apply_unary_op(ops.dayofweek_op) + @property + def day_of_week(self) -> series.Series: + return self.dayofweek + @property def dayofyear(self) -> series.Series: return self._apply_unary_op(ops.dayofyear_op) + @property + def day_of_year(self) -> series.Series: + return self.dayofyear + @property def date(self) -> series.Series: return self._apply_unary_op(ops.date_op) diff --git a/tests/system/small/operations/test_datetimes.py b/tests/system/small/operations/test_datetimes.py index 8ce0cb9beb..1462a68b49 100644 --- a/tests/system/small/operations/test_datetimes.py +++ b/tests/system/small/operations/test_datetimes.py @@ -86,12 +86,28 @@ def test_dt_dayofweek(scalars_dfs, col_name): pytest.importorskip("pandas", minversion="2.0.0") scalars_df, scalars_pandas_df = scalars_dfs bf_series: bigframes.series.Series = scalars_df[col_name] + bf_result = bf_series.dt.dayofweek.to_pandas() pd_result = scalars_pandas_df[col_name].dt.dayofweek assert_series_equal(pd_result, bf_result, check_dtype=False) +@pytest.mark.parametrize( + ("col_name",), + DATE_COLUMNS, +) +def test_dt_day_of_week(scalars_dfs, col_name): + pytest.importorskip("pandas", minversion="2.0.0") + scalars_df, scalars_pandas_df = scalars_dfs + bf_series: bigframes.series.Series = scalars_df[col_name] + + bf_result = bf_series.dt.day_of_week.to_pandas() + pd_result = scalars_pandas_df[col_name].dt.day_of_week + + assert_series_equal(pd_result, bf_result, check_dtype=False) + + @pytest.mark.parametrize( ("col_name",), DATE_COLUMNS, @@ -100,12 +116,28 @@ def test_dt_dayofyear(scalars_dfs, col_name): pytest.importorskip("pandas", minversion="2.0.0") scalars_df, scalars_pandas_df = scalars_dfs bf_series: bigframes.series.Series = scalars_df[col_name] + bf_result = bf_series.dt.dayofyear.to_pandas() pd_result = scalars_pandas_df[col_name].dt.dayofyear assert_series_equal(pd_result, bf_result, check_dtype=False) +@pytest.mark.parametrize( + ("col_name",), + DATE_COLUMNS, +) +def test_dt_day_of_year(scalars_dfs, col_name): + pytest.importorskip("pandas", minversion="2.0.0") + scalars_df, scalars_pandas_df = scalars_dfs + bf_series: bigframes.series.Series = scalars_df[col_name] + + bf_result = bf_series.dt.day_of_year.to_pandas() + pd_result = scalars_pandas_df[col_name].dt.day_of_year + + assert_series_equal(pd_result, bf_result, check_dtype=False) + + @pytest.mark.parametrize( ("col_name",), DATETIME_COL_NAMES, diff --git a/third_party/bigframes_vendored/pandas/core/indexes/accessor.py b/third_party/bigframes_vendored/pandas/core/indexes/accessor.py index dfb1cf9efc..0dd487d056 100644 --- a/third_party/bigframes_vendored/pandas/core/indexes/accessor.py +++ b/third_party/bigframes_vendored/pandas/core/indexes/accessor.py @@ -66,6 +66,40 @@ def dayofweek(self): raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) + @property + def day_of_week(self): + """The day of the week with Monday=0, Sunday=6. + + Return the day of the week. It is assumed the week starts on + Monday, which is denoted by 0 and ends on Sunday, which is denoted + by 6. + + **Examples:** + + >>> import pandas as pd + >>> import bigframes.pandas as bpd + >>> bpd.options.display.progress_bar = None + >>> s = bpd.Series( + ... pd.date_range('2016-12-31', '2017-01-08', freq='D').to_series() + ... ) + >>> s.dt.day_of_week + 2016-12-31 00:00:00 5 + 2017-01-01 00:00:00 6 + 2017-01-02 00:00:00 0 + 2017-01-03 00:00:00 1 + 2017-01-04 00:00:00 2 + 2017-01-05 00:00:00 3 + 2017-01-06 00:00:00 4 + 2017-01-07 00:00:00 5 + 2017-01-08 00:00:00 6 + dtype: Int64 + + Returns: + Series: Containing integers indicating the day number. + """ + + raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) + @property def dayofyear(self): """The ordinal day of the year. @@ -94,6 +128,34 @@ def dayofyear(self): raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) + @property + def day_of_year(self): + """The ordinal day of the year. + + **Examples:** + + >>> import pandas as pd + >>> import bigframes.pandas as bpd + >>> bpd.options.display.progress_bar = None + >>> s = bpd.Series( + ... pd.date_range('2016-12-28', '2017-01-03', freq='D').to_series() + ... ) + >>> s.dt.day_of_year + 2016-12-28 00:00:00 363 + 2016-12-29 00:00:00 364 + 2016-12-30 00:00:00 365 + 2016-12-31 00:00:00 366 + 2017-01-01 00:00:00 1 + 2017-01-02 00:00:00 2 + 2017-01-03 00:00:00 3 + dtype: Int64 + + Returns: + Series: Containing integers indicating the day number. + """ + + raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE) + @property def date(self): """Returns a Series with the date part of Timestamps without time and