如何获取 pandas 数据框列在给定月份的天数?
How to get the number of days in given month for a pandas dataframe column?
尝试为 ML 算法编码循环特征,其中时间戳特征作为特征非常重要。
我想将 day_in_month(cyclic_df 的 'day' 列)转换为循环变量,以便一个月的第一天在前一天的最后一天之后.所以 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 的每一行中,我有一列 'month'、一列 'year' 和一列 'day'。所以理论上,应该有一个解决方案来读取给定月份的正确天数。我如何用正确的变量替换 30(上面代码中的第 5 行和第 6 行),以便它从其他列读取年份和月份,并替换为正确的值,而不是总是 30?
PS:如果有人能告诉我,如果我在每一分钟、每一小时和每一月都做对了,那就太好了,也可以在上面的代码中找到。
编辑(评论后):
是的,我有一个 'year' 列。并将这两行更改为:
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().
如果你的数据中有年份和月份,你可以使用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))
我不太明白你在用三角函数做什么 - 要么你没有很好地解释你的目标,要么你过度设计了解决方案。
year/month/day 约定是一种人类便利。为了直接比较天数,时间是使用自商定纪元以来的时间单位数来衡量的。最常见的情况是 Unix 时间戳,它计算自 1970 年 1 月 1 日以来的秒数。
因此您有两个选择:
- 您可以将所有时间转换为 Unix 时间戳,然后将它们从秒转换为天。
- 解释了将日期转换为时间戳here。该问题假定解析字符串,但您也可以使用实际日期值实例化
datetime
。
- 如果
s
是秒,可以用d = s/(24*60*60)
得到天数
- 您可以切换到自己的基于天的系统。
- 设置任意 "epoch date" 后,您可以按照 here.
中所述获取 table 中的纪元和任何日期之间的天数
尝试为 ML 算法编码循环特征,其中时间戳特征作为特征非常重要。
我想将 day_in_month(cyclic_df 的 'day' 列)转换为循环变量,以便一个月的第一天在前一天的最后一天之后.所以 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 的每一行中,我有一列 'month'、一列 'year' 和一列 'day'。所以理论上,应该有一个解决方案来读取给定月份的正确天数。我如何用正确的变量替换 30(上面代码中的第 5 行和第 6 行),以便它从其他列读取年份和月份,并替换为正确的值,而不是总是 30?
PS:如果有人能告诉我,如果我在每一分钟、每一小时和每一月都做对了,那就太好了,也可以在上面的代码中找到。
编辑(评论后): 是的,我有一个 'year' 列。并将这两行更改为:
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().
如果你的数据中有年份和月份,你可以使用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))
我不太明白你在用三角函数做什么 - 要么你没有很好地解释你的目标,要么你过度设计了解决方案。
year/month/day 约定是一种人类便利。为了直接比较天数,时间是使用自商定纪元以来的时间单位数来衡量的。最常见的情况是 Unix 时间戳,它计算自 1970 年 1 月 1 日以来的秒数。
因此您有两个选择:
- 您可以将所有时间转换为 Unix 时间戳,然后将它们从秒转换为天。
- 解释了将日期转换为时间戳here。该问题假定解析字符串,但您也可以使用实际日期值实例化
datetime
。 - 如果
s
是秒,可以用d = s/(24*60*60)
得到天数
- 解释了将日期转换为时间戳here。该问题假定解析字符串,但您也可以使用实际日期值实例化
- 您可以切换到自己的基于天的系统。
- 设置任意 "epoch date" 后,您可以按照 here. 中所述获取 table 中的纪元和任何日期之间的天数