Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into issue-106
Browse files Browse the repository at this point in the history
  • Loading branch information
d.a.bunin committed Sep 28, 2021
2 parents 817dbf5 + d45201d commit 5b3364e
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Examples to TSDataset methods with doctest ([#92](https://github.com/tinkoff-ai/etna-ts/pull/92))
- WandbLogger ([#71](https://github.com/tinkoff-ai/etna-ts/pull/71))
- Pipeline ([#78](https://github.com/tinkoff-ai/etna-ts/pull/78))
- 'is_weekend' feature in DateFlagsTransform ([#101](https://github.com/tinkoff-ai/etna-ts/pull/101))

### Changed
- SklearnTransform out column names ([#99](https://github.com/tinkoff-ai/etna-ts/pull/99))
Expand Down
16 changes: 15 additions & 1 deletion etna/transforms/datetime_flags.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ def __init__(
week_number_in_year: Optional[bool] = False,
month_number_in_year: Optional[bool] = False,
year_number: Optional[bool] = False,
is_weekend: Optional[bool] = True,
special_days_in_week: Sequence[int] = (),
special_days_in_month: Sequence[int] = (),
):
Expand All @@ -46,6 +47,8 @@ def __init__(
if True, add column "month_number_in_year" with month info to feature dataframe in transform
year_number:
if True, add column "year_number" with year info to feature dataframe in transform
is_weekend:
if True: add column "regressor_is_weekend" with weekends flags to feature dataframe in transform
special_days_in_week:
list of weekdays number (from [0, 6]) that should be interpreted as special ones, if given add column
"special_days_in_week" with flag that shows given date is a special day
Expand Down Expand Up @@ -77,14 +80,15 @@ def __init__(
week_number_in_year,
month_number_in_year,
year_number,
is_weekend,
special_days_in_week,
special_days_in_month,
]
):
raise ValueError(
f"{type(self).__name__} feature does nothing with given init args configuration, "
f"at least one of day_number_in_week, day_number_in_month, week_number_in_month, "
f"week_number_in_year, month_number_in_year, year_number should be True or any of "
f"week_number_in_year, month_number_in_year, year_number, is_weekend should be True or any of "
f"specyal_days_in_week, special_days_in_month should be not empty."
)

Expand All @@ -94,6 +98,7 @@ def __init__(
self.week_number_in_year = week_number_in_year
self.month_number_in_year = month_number_in_year
self.year_number = year_number
self.is_weekend = is_weekend

self.special_days_in_week = special_days_in_week
self.special_days_in_month = special_days_in_month
Expand Down Expand Up @@ -137,6 +142,9 @@ def transform(self, df: pd.DataFrame) -> pd.DataFrame:
if self.year_number:
features["year_number"] = self._get_year(timestamp_series=timestamp_series)

if self.is_weekend:
features["is_weekend"] = self._get_weekends(timestamp_series=timestamp_series)

if self.special_days_in_week:
features["special_days_in_week"] = self._get_special_day_in_week(
special_days=self.special_days_in_week, timestamp_series=timestamp_series
Expand Down Expand Up @@ -233,6 +241,12 @@ def _get_year(timestamp_series: pd.Series) -> np.array:
"""Generate an array with the week number in the year."""
return timestamp_series.apply(lambda x: x.year).values

@staticmethod
def _get_weekends(timestamp_series: pd.Series) -> np.array:
"""Generate an array with the weekends flags."""
weekend_days = (5, 6)
return timestamp_series.apply(lambda x: x.weekday() in weekend_days).values


class TimeFlagsTransform(Transform):
"""Class for holding time transform."""
Expand Down
4 changes: 2 additions & 2 deletions tests/test_model_selection/test_backtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,7 @@ def test_get_metrics_interface(aggregate_metrics: bool, expected_columns: List[s

def test_get_forecasts_interface_daily(big_daily_example_tsdf: TSDataset):
"""Test interface of TimeSeriesCrossValidation.get_forecasts"""
date_flags = DateFlagsTransform(day_number_in_week=True, day_number_in_month=True)
date_flags = DateFlagsTransform(day_number_in_week=True, day_number_in_month=True, is_weekend=False)
tsvc = _fit_backtest_pipeline(
model=CatBoostModelMultiSegment(), horizon=24, ts=big_daily_example_tsdf, transforms=[date_flags]
)
Expand All @@ -271,7 +271,7 @@ def test_get_forecasts_interface_daily(big_daily_example_tsdf: TSDataset):

def test_get_forecasts_interface_hours(example_tsdf: TSDataset):
"""Test interface of TimeSeriesCrossValidation.get_forecasts"""
date_flags = DateFlagsTransform(day_number_in_week=True, day_number_in_month=True)
date_flags = DateFlagsTransform(day_number_in_week=True, day_number_in_month=True, is_weekend=False)
tsvc = _fit_backtest_pipeline(
model=CatBoostModelMultiSegment(), horizon=24, ts=example_tsdf, transforms=[date_flags]
)
Expand Down
12 changes: 10 additions & 2 deletions tests/test_transforms/test_dateflags_transform.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,18 @@

from etna.transforms.datetime_flags import DateFlagsTransform

WEEKEND_DAYS = (5, 6)
SPECIAL_DAYS = [1, 4]
INIT_PARAMS_TEMPLATE = {
"day_number_in_week": False,
"day_number_in_month": False,
"week_number_in_year": False,
"week_number_in_month": False,
"month_number_in_year": False,
"year_number": False,
"is_weekend": False,
"special_days_in_week": (),
"special_days_in_month": (),
"year_number": False,
}


Expand All @@ -46,6 +48,7 @@ def dateflags_true_df() -> pd.DataFrame:
df["week_number_in_month"] = df["timestamp"].apply(
lambda x: int(x.weekday() < (x - timedelta(days=x.day - 1)).weekday()) + (x.day - 1) // 7 + 1
)
df["is_weekend"] = df["timestamp"].apply(lambda x: x.weekday() in WEEKEND_DAYS)
df["special_days_in_week"] = df["day_number_in_week"].apply(lambda x: x in SPECIAL_DAYS)
df["special_days_in_month"] = df["day_number_in_month"].apply(lambda x: x in SPECIAL_DAYS)

Expand Down Expand Up @@ -93,6 +96,7 @@ def test_invalid_arguments_configuration():
week_number_in_year=False,
month_number_in_year=False,
year_number=False,
is_weekend=False,
special_days_in_week=(),
special_days_in_month=(),
)
Expand All @@ -108,13 +112,14 @@ def test_repr():
week_number_in_year=False,
month_number_in_year=True,
year_number=True,
is_weekend=True,
special_days_in_week=(1, 2),
special_days_in_month=(12,),
)
transform_repr = transform.__repr__()
true_repr = (
f"{transform_class_repr}(day_number_in_week = True, day_number_in_month = True, week_number_in_month = False, "
f"week_number_in_year = False, month_number_in_year = True, year_number = True, special_days_in_week = (1, 2), "
f"week_number_in_year = False, month_number_in_year = True, year_number = True, is_weekend = True, special_days_in_week = (1, 2), "
f"special_days_in_month = (12,), )"
)
assert transform_repr == true_repr
Expand All @@ -129,13 +134,15 @@ def test_repr():
["week_number_in_month"],
["month_number_in_year"],
["year_number"],
["is_weekend"],
[
"day_number_in_week",
"day_number_in_month",
"week_number_in_year",
"week_number_in_month",
"month_number_in_year",
"year_number",
"is_weekend",
],
),
)
Expand Down Expand Up @@ -192,6 +199,7 @@ def test_interface_correct_tuple_args(true_params: List[str], train_df: pd.DataF
{"week_number_in_month": True},
{"month_number_in_year": True},
{"year_number": True},
{"is_weekend": True},
{"special_days_in_week": SPECIAL_DAYS},
{"special_days_in_month": SPECIAL_DAYS},
),
Expand Down

0 comments on commit 5b3364e

Please sign in to comment.