Skip to content

Commit 9d4a59d

Browse files
authored
feat: Add "dayofyear" property for dt accessors (#1692)
* implement dayofyear. tests to follow * add tests * add Python doc
1 parent 67d8760 commit 9d4a59d

File tree

6 files changed

+61
-0
lines changed

6 files changed

+61
-0
lines changed

bigframes/core/compile/scalar_op_compiler.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -676,6 +676,13 @@ def dayofweek_op_impl(x: ibis_types.Value):
676676
)
677677

678678

679+
@scalar_op_compiler.register_unary_op(ops.dayofyear_op)
680+
def dayofyear_op_impl(x: ibis_types.Value):
681+
return (
682+
typing.cast(ibis_types.TimestampValue, x).day_of_year().cast(ibis_dtypes.int64)
683+
)
684+
685+
679686
@scalar_op_compiler.register_unary_op(ops.hour_op)
680687
def hour_op_impl(x: ibis_types.Value):
681688
return typing.cast(ibis_types.TimestampValue, x).hour().cast(ibis_dtypes.int64)

bigframes/operations/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
date_diff_op,
4343
day_op,
4444
dayofweek_op,
45+
dayofyear_op,
4546
month_op,
4647
quarter_op,
4748
year_op,
@@ -261,6 +262,7 @@
261262
"month_op",
262263
"year_op",
263264
"dayofweek_op",
265+
"dayofyear_op",
264266
"quarter_op",
265267
# Time ops
266268
"hour_op",

bigframes/operations/date_ops.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,11 @@
3939
type_signature=op_typing.DATELIKE_ACCESSOR,
4040
)
4141

42+
dayofyear_op = base_ops.create_unary_op(
43+
name="dayofyear",
44+
type_signature=op_typing.DATELIKE_ACCESSOR,
45+
)
46+
4247
quarter_op = base_ops.create_unary_op(
4348
name="quarter",
4449
type_signature=op_typing.DATELIKE_ACCESSOR,

bigframes/operations/datetimes.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ def day(self) -> series.Series:
4343
def dayofweek(self) -> series.Series:
4444
return self._apply_unary_op(ops.dayofweek_op)
4545

46+
@property
47+
def dayofyear(self) -> series.Series:
48+
return self._apply_unary_op(ops.dayofyear_op)
49+
4650
@property
4751
def date(self) -> series.Series:
4852
return self._apply_unary_op(ops.date_op)

tests/system/small/operations/test_datetimes.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,20 @@ def test_dt_dayofweek(scalars_dfs, col_name):
8181
assert_series_equal(pd_result, bf_result, check_dtype=False)
8282

8383

84+
@pytest.mark.parametrize(
85+
("col_name",),
86+
DATE_COLUMNS,
87+
)
88+
def test_dt_dayofyear(scalars_dfs, col_name):
89+
pytest.importorskip("pandas", minversion="2.0.0")
90+
scalars_df, scalars_pandas_df = scalars_dfs
91+
bf_series: bigframes.series.Series = scalars_df[col_name]
92+
bf_result = bf_series.dt.dayofyear.to_pandas()
93+
pd_result = scalars_pandas_df[col_name].dt.dayofyear
94+
95+
assert_series_equal(pd_result, bf_result, check_dtype=False)
96+
97+
8498
@pytest.mark.parametrize(
8599
("col_name",),
86100
DATETIME_COL_NAMES,

third_party/bigframes_vendored/pandas/core/indexes/accessor.py

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,35 @@ def dayofweek(self):
6666

6767
raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE)
6868

69+
@property
70+
def dayofyear(self):
71+
"""The ordinal day of the year.
72+
73+
**Examples:**
74+
75+
>>> import pandas as pd
76+
>>> import bigframes.pandas as bpd
77+
>>> bpd.options.display.progress_bar = None
78+
>>> s = bpd.Series(
79+
... pd.date_range('2016-12-28', '2017-01-03', freq='D').to_series()
80+
... )
81+
>>> s.dt.dayofyear
82+
2016-12-28 00:00:00 363
83+
2016-12-29 00:00:00 364
84+
2016-12-30 00:00:00 365
85+
2016-12-31 00:00:00 366
86+
2017-01-01 00:00:00 1
87+
2017-01-02 00:00:00 2
88+
2017-01-03 00:00:00 3
89+
dtype: Int64
90+
dtype: Int64
91+
92+
Returns:
93+
Series: Containing integers indicating the day number.
94+
"""
95+
96+
raise NotImplementedError(constants.ABSTRACT_METHOD_ERROR_MESSAGE)
97+
6998
@property
7099
def date(self):
71100
"""Returns a Series with the date part of Timestamps without time and

0 commit comments

Comments
 (0)