如何获取给定月份中熊猫数据框列的天数?

时间:2018-12-06 20:19:41

标签: python pandas feature-extraction feature-selection feature-engineering

尝试为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().

2 个答案:

答案 0 :(得分:1)

我不太了解您在使用三角函数所做的事情-您没有很好地说明目标,或者您对解决方案的设计过度。

年/月/日的惯例很方便。为了直接比较天数,使用商定的时期以来的时间单位数来测量时间。最常见的情况是Unix时间戳记,该时间戳记自1970年1月1日以来的秒数。

因此,您有两个选择:

  • 您可以将所有时间转换为Unix时间戳,然后将它们从几秒转换为几天。
    • 将日期转换为时间戳的说明here。该问题假定解析字符串,但是您也可以使用实际的日期值实例化datetime
    • 如果s是秒,则可以使用d = s/(24*60*60)获得天数
  • 您可以切换到自己的日间系统。
    • 设置了任意的“纪元日期”后,您可以按照here的说明获取纪元与表中任何日期之间的天数。

答案 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))
相关问题