my-tide-env / utils /timefeatures.py
alwaysgood's picture
Update utils/timefeatures.py
da082ac verified
# 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)