如何解决在Python中给定日期列表作为DateTime对象的情况下,如何计算每个月的第一个星期五?
假设我在Python中有一个DateTimeIndex
对象,存储为trading_days
:
DatetimeIndex(['2014-01-02','2014-01-03','2014-01-06','2014-01-07','2014-01-08','2014-01-09','2014-01-10','2014-01-13','2014-01-14','2014-01-15',...
'2017-12-15','2017-12-18','2017-12-19','2017-12-20','2017-12-21','2017-12-22','2017-12-26','2017-12-27','2017-12-28','2017-12-29'],dtype='datetime64[ns]',length=1007,freq=None)
我想计算此DateTime对象中每个月的第一个星期五。我想要的输出是另一个DateTime对象,这些对象具有第一个星期五的这些日期。
我的尝试如下:
all_fridays = trading_days[trading_days.day_name() == 'Friday']
first_fridays = all_fridays[np.remainder(np.arange(len(all_fridays)),4) == 0]
但是,例如,如果某个月份有5个星期五,则此代码将失败。 例如,我从上面的代码获得的输出是
DatetimeIndex(['2014-01-03','2014-01-31','2014-02-28','2014-03-28','2014-05-02','2014-05-30','2014-06-27','2014-08-01','2014-08-29','2014-09-26','2014-10-24','2014-11-21','2014-12-19','2015-01-16','2015-02-13','2015-03-13','2015-04-17','2015-05-15','2015-06-12','2015-07-17','2015-08-14','2015-09-11','2015-10-09','2015-11-06','2015-12-04','2016-01-15','2016-02-12','2016-03-11','2016-04-15','2016-05-13','2016-06-10','2016-07-08','2016-08-05','2016-09-02','2016-09-30','2016-10-28','2016-11-25','2016-12-23','2017-01-20','2017-02-17','2017-03-17','2017-04-21','2017-05-19','2017-06-16','2017-07-14','2017-08-11','2017-09-08','2017-10-06','2017-11-03','2017-12-01',freq=None)
2014年1月很容易出现我刚刚描述的错误。然后一切都搞砸了。
如何有效地做到这一点?我觉得Pandas
应该已经内置了类似的东西,但是找不到。非常感谢!
解决方法
不能100%确定如何重新创建示例DatetimeIndex,但我们将从简单的bdate_range
开始。
细分为星期五,然后在年份-月份期间删除重复项
import pandas as pd
trading_days = pd.bdate_range('2014-01-02',freq='C',periods=1007,weekmask='Mon Tue Wed Thu Fri')
fridays = trading_days[trading_days.dayofweek == 4]
fridays = fridays[~fridays.to_period('M').duplicated()]
#DatetimeIndex(['2014-01-03','2014-02-07','2014-03-07','2014-04-04',# '2014-05-02','2014-06-06','2014-07-04','2014-08-01',# ...
# '2017-05-05','2017-06-02','2017-07-07','2017-08-04',# '2017-09-01','2017-10-06','2017-11-03'],# dtype='datetime64[ns]',name='date',freq=None)
,
当您找到阵列的第一个星期五时,以下逻辑可以为您提供帮助。
让我们说第一个星期五是2014年1月3日,然后检查末尾第4位的数字(我正在考虑将“-”作为位置),现在将28加到当前索引中。如果接收到的日期在倒数第4位也与上一个第4位相同,则将索引再加上7,该索引将成为下个月的第一个星期五,否则将其加28下个月的第一个星期五。
在这里,由于过去3个月(即10、11和12)的最后一位数字与前任不同,因此您无需检查第5位。
使用pyhton中的if else条件,可以轻松实现以上所有解释。
,这是一个简单的函数,它将从熊猫的DatetimeIndex中提取每个月的第一个星期五(或每个月的第四个星期四,或...)。使用sign(colSums(mymat))
[1] 1 -1 -1 1 1
函数是一个借口。
itertools.groupby()
使用如下功能:
import pandas as pd
from itertools import groupby
def get_one_date_per_month(dates,rank='first',day_name='Friday'):
rank_to_idx = {'first': 0,'second': 1,'third': 2,'fourth': 3,'last': -1}
idx = rank_to_idx[rank]
dates = [d
for d in dates
if d.day_name() == day_name]
filtered_dates = []
for k,g in groupby(dates,key=lambda x: x.strftime('%Y-%m')):
t = list(g)
filtered_dates.append(t[idx])
return filtered_dates
,
不确定这比已经发布的其他答案要好。但是根据您的问题,我从DatetimeIndex
中的日期开始:
index = pd.DatetimeIndex(pd.date_range('2014-01-02','2017-12-19')) # some dates
dates_by_month = index.groupby(index.to_period("M"))
first_fridays = pd.Series({period: dates[dates.weekday == 4][0]
for period,dates in dates_by_month.items()})
first_fridays.head()
2014-01 2014-01-03
2014-02 2014-02-07
2014-03 2014-03-07
2014-04 2014-04-04
2014-05 2014-05-02
Freq: M,dtype: datetime64[ns]
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。