在Python中,如果将日期列表作为DateTime对象,如何计算每个月的第一个星期五?
假设在Python中有一个在Python中,如果将日期列表作为DateTime对象,如何计算每个月的第一个星期五?,python,pandas,dataframe,datetime,Python,Pandas,Dataframe,Datetime,假设在Python中有一个DateTimeIndex对象存储为trading\u 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', ...
DateTimeIndex
对象存储为trading\u 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', '2017-12-29'],
dtype='datetime64[ns]', freq=None)
2014年1月很容易出现我刚才描述的错误。然后一切都搞砸了
我怎样才能有效地完成它?我觉得熊猫应该已经内置了类似的东西,但我找不到。非常感谢 无法100%确定如何重新创建示例DatetimeIndex,但我们将从一个简单的
bdate\u范围开始
子集到星期五,然后在年-月期间删除重复项
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)
无法100%确定如何重新创建示例DatetimeIndex,但我们将从一个简单的bdate\u范围开始
子集到星期五,然后在年-月期间删除重复项
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-01-03,然后检查末尾第4位的数字(我考虑将“-”作为一个位置),现在将28添加到当前指数中。如果收到的日期在倒数第4位的数字与前一个相同,则在索引中再添加7,该索引将是下个月的第一个星期五,否则,通过添加28获得的索引将是下个月的第一个星期五
在这里,您不需要检查第5位,因为过去3个月,即10、11和12,所有位置的最后一位数字都与前一位不同
使用pyhton中的if-else条件可以轻松实现上述所有解释。当您找到数组的第一个星期五时,以下逻辑可以帮助您
假设第一个星期五是2014-01-03,然后检查末尾第4位的数字(我考虑将“-”作为一个位置),现在将28添加到当前指数中。如果收到的日期在倒数第4位的数字与前一个相同,则在索引中再添加7,该索引将是下个月的第一个星期五,否则,通过添加28获得的索引将是下个月的第一个星期五
在这里,您不需要检查第5位,因为过去3个月,即10、11和12,所有位置的最后一位数字都与前一位不同
使用pyhton中的if-else条件可以轻松实现上述所有解释。这里有一个简单的函数,它将从pandas DatetimeIndex中提取每个月的第一个星期五(或每个月的第四个星期四,或…)。这是使用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
使用如下函数:
# use your list of trading days, or `dates` for illustration:
dates = pd.date_range(start='2014-01-01', end='2017-12-31', freq='D')
get_one_date_per_month(dates)[:3]
# results are:
[Timestamp('2014-01-03 00:00:00', freq='D'),
Timestamp('2014-02-07 00:00:00', freq='D'),
Timestamp('2014-03-07 00:00:00', freq='D')]
下面是一个简单的函数,它将从pandas DatetimeIndex中提取每个月的第一个星期五(或每个月的第四个星期四,或…)。这是使用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
使用如下函数:
# use your list of trading days, or `dates` for illustration:
dates = pd.date_range(start='2014-01-01', end='2017-12-31', freq='D')
get_one_date_per_month(dates)[:3]
# results are:
[Timestamp('2014-01-03 00:00:00', freq='D'),
Timestamp('2014-02-07 00:00:00', freq='D'),
Timestamp('2014-03-07 00:00:00', freq='D')]
不确定这比已经发布的其他答案好。但根据您的问题,我从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]
不确定这比已经发布的其他答案好。但根据您的问题,我从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]