# utils/timefeatures.py (최종 수정 버전) import numpy as np import pandas as pd from typing import List # ------------------------------------------------------------------------- # 이 파일의 모든 코드를 아래 내용으로 교체하면 됩니다. # ------------------------------------------------------------------------- class BaseTimeFeature: def __call__(self, index: pd.DatetimeIndex) -> np.ndarray: pass class SecondOfMinute(BaseTimeFeature): """Minute of hour encoded as value between [-0.5, 0.5]""" def __call__(self, index: pd.DatetimeIndex) -> np.ndarray: # ⭐️ 수정: index.second -> index.dt.second return index.dt.second / 59.0 - 0.5 class MinuteOfHour(BaseTimeFeature): """Minute of hour encoded as value between [-0.5, 0.5]""" def __call__(self, index: pd.DatetimeIndex) -> np.ndarray: # ⭐️ 수정: index.minute -> index.dt.minute return index.dt.minute / 59.0 - 0.5 class HourOfDay(BaseTimeFeature): """Hour of day encoded as value between [-0.5, 0.5]""" def __call__(self, index: pd.DatetimeIndex) -> np.ndarray: # ⭐️ 수정: index.hour -> index.dt.hour return index.dt.hour / 23.0 - 0.5 class DayOfWeek(BaseTimeFeature): """Day of week encoded as value between [-0.5, 0.5]""" def __call__(self, index: pd.DatetimeIndex) -> np.ndarray: # ⭐️ 수정: index.dayofweek -> index.dt.dayofweek return index.dt.dayofweek / 6.0 - 0.5 class DayOfMonth(BaseTimeFeature): """Day of month encoded as value between [-0.5, 0.5]""" def __call__(self, index: pd.DatetimeIndex) -> np.ndarray: # ⭐️ 수정: index.day -> index.dt.day return (index.dt.day - 1) / 30.0 - 0.5 class DayOfYear(BaseTimeFeature): """Day of year encoded as value between [-0.5, 0.5]""" def __call__(self, index: pd.DatetimeIndex) -> np.ndarray: # ⭐️ 수정: index.dayofyear -> index.dt.dayofyear return (index.dt.dayofyear - 1) / 365.0 - 0.5 class MonthOfYear(BaseTimeFeature): """Month of year encoded as value between [-0.5, 0.5]""" def __call__(self, index: pd.DatetimeIndex) -> np.ndarray: # ⭐️ 수정: index.month -> index.dt.month return (index.dt.month - 1) / 11.0 - 0.5 class WeekOfYear(BaseTimeFeature): """Week of year encoded as value between [-0.5, 0.5]""" def __call__(self, index: pd.DatetimeIndex) -> np.ndarray: # ⭐️ 수정: index.isocalendar().week -> index.dt.isocalendar().week # .astype(float) 추가 return (index.dt.isocalendar().week.astype(float) - 1) / 52.0 - 0.5 def time_features_from_frequency_str(freq_str: str) -> List[BaseTimeFeature]: """ Returns a list of time features that will be used for a given frequency string. """ features_by_offsets = { "Y": ["year"], "M": ["month", "year"], "W": ["day", "week", "month", "year"], "D": ["day", "week", "month", "year"], "B": ["day", "week", "month", "year"], "H": ["hour", "day", "week", "month", "year"], "T": ["minute", "hour", "day", "week", "month", "year"], "min": ["minute", "hour", "day", "week", "month", "year"], "S": ["second", "minute", "hour", "day", "week", "month", "year"], } offset = freq_str.split("-")[-1] for name, feats in features_by_offsets.items(): if offset.startswith(name): return [ cls() for cls in FEATURES_MAP.values() if cls.name in feats ] FEATURES_MAP = { "year": "Year", "month": MonthOfYear, "week": WeekOfYear, "day": DayOfMonth, "dayofweek": DayOfWeek, "dayofyear": DayOfYear, "hour": HourOfDay, "minute": MinuteOfHour, "second": SecondOfMinute, } def time_features(dates, freq="T"): # ⭐️ 이 함수 내부 로직을 pandas 최신 버전에 맞게 수정했습니다. if isinstance(dates, pd.DataFrame): dates = pd.to_datetime(dates.iloc[:, 0]) return np.vstack( [feat(dates) for feat in time_features_from_frequency_str(freq)] ).transpose(1, 0)