尝试为ML算法编码循环特征,其中时间戳特征作为特征非常重要。
我想将day_in_month(cyclic_df的“ day”列)转换为周期性变量,以便每月的1号位于前一个的最后一天之后。因此,2月1日(01.02)接近1月31日(31.01),因此,如果仅考虑天列,则2天之间的差是1,而不是30!
# Transform the cyclical features
cyclic_df['min_sin'] = np.sin(cyclic_df.minute*(2.*np.pi/59)) # Sinus component of minute
cyclic_df['min_cos'] = np.cos(cyclic_df.minute*(2.*np.pi/59)) # Cosinus component of minute
cyclic_df['hr_sin'] = np.sin(cyclic_df.hour*(2.*np.pi/23)) # Sinus component of hour
cyclic_df['hr_cos'] = np.cos(cyclic_df.hour*(2.*np.pi/23)) # Cosinus component of hour
cyclic_df['d_sin'] = np.sin(cyclic_df.day*(2.*np.pi/30)) # !!!Sinus component of day!!!! Help here
cyclic_df['d_cos'] = np.cos(cyclic_df.day*(2.*np.pi/30)) # !!!Cosinus component of day!!! Help here
cyclic_df['mnth_sin'] = np.sin((cyclic_df.month-1)*(2.*np.pi/12)) # Sinus component of minute
cyclic_df['mnth_cos'] = np.cos((cyclic_df.month-1)*(2.*np.pi/12)) # Cosinus component of minute
问题在于我除以30。并非每个月都有30天,有几个月有30、31、28或29天。在cyclical_df的每一行中,我都有一列“月”,一列“年”和一列“天”。因此,从理论上讲,应该有一个解决方案,可以读取给定月份的正确天数。我如何用正确的变量替换那30(上面代码中的第5行和第6行),以便它从其他列中读取年和月,并用正确的值替换,而不总是30?
PS:如果有人告诉我,如果我在分钟,小时和月中做的正确,那将非常好,上面的代码也提供了此信息。
编辑(在评论后): 是的,我有一个“年份”列。并将两行更改为:
cyclic_ext_df['d_cos'] = np.cos(cyclic_ext_df.day*(2.*np.pi/monthrange(cyclic_df.year, cyclic_ext_df.month)[1]))
cyclic_ext_df['d_cos'] = np.cos(cyclic_ext_df.day*(2.*np.pi/monthrange(cyclic_df.year, cyclic_ext_df.month)[1]))
我收到以下错误:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-575-532a308075e2> in <module>()
11 #cyclic_ext_df['d_cos'] = np.cos(cyclic_ext_df.day*(2.*np.pi/30)) # Cosinus component of day
12
---> 13 cyclic_ext_df['d_cos'] = np.cos(cyclic_ext_df.day*(2.*np.pi/monthrange(cyclic_df.year, cyclic_ext_df.month)[1]))
14 cyclic_ext_df['d_cos'] = np.cos(cyclic_ext_df.day*(2.*np.pi/monthrange(cyclic_df.year, cyclic_ext_df.month)[1]))
15
~/anaconda/lib/python3.6/calendar.py in monthrange(year, month)
120 """Return weekday (0-6 ~ Mon-Sun) and number of days (28-31) for
121 year, month."""
--> 122 if not 1 <= month <= 12:
123 raise IllegalMonthError(month)
124 day1 = weekday(year, month, 1)
~/anaconda/lib/python3.6/site-packages/pandas/core/generic.py in __nonzero__(self)
1574 raise ValueError("The truth value of a {0} is ambiguous. "
1575 "Use a.empty, a.bool(), a.item(), a.any() or a.all()."
-> 1576 .format(self.__class__.__name__))
1577
1578 __bool__ = __nonzero__
ValueError: The truth value of a Series is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
答案 0 :(得分:1)
我不太了解您在使用三角函数所做的事情-您没有很好地说明目标,或者您对解决方案的设计过度。
年/月/日的惯例很方便。为了直接比较天数,使用商定的时期以来的时间单位数来测量时间。最常见的情况是Unix时间戳记,该时间戳记自1970年1月1日以来的秒数。
因此,您有两个选择:
答案 1 :(得分:0)
如果您的数据中包含年份和月份,则可以使用calendar.monthrange
:
from calendar import monthrange
month = 2
year = 2014
_, mr = monthrange(year, month)
cyclic_df['d_cos'] = np.cos(cyclic_df.day*(2.*np.pi/mr))