使用pandas
可以轻松创建月度系列日期。
import pandas as pd
pd.date_range('2012-04-23', '2013-01-23', freq='BM')
DatetimeIndex(['2012-04-30', '2012-05-31', '2012-06-29', '2012-07-31',
'2012-08-31', '2012-09-28', '2012-10-31', '2012-11-30',
'2012-12-31'],
dtype='datetime64[ns]', freq='BM')
请注意DatetimeIndex
中的日期是月末。我知道我应该考虑选择freq='BM'
,但我不相信我有一个可以完成目标的选择。
我经常需要从每个月的最后一个工作日开始每月制作一系列日期。
我希望看到这一点:
DatetimeIndex(['2012-04-23', '2012-05-23', '2012-06-23', '2012-07-23',
'2012-08-23', '2012-09-23', '2012-10-23', '2012-11-23',
'2012-12-23'],
dtype='datetime64[ns]', freq=None)
或另一个更复杂的例子可能是从2012-01-30' 2012-01-30'到' 2012-04-30'。我希望看到:
DatetimeIndex(['2012-01-30', '2012-02-29', '2012-03-30', '2012-04-30'],
dtype='datetime64[ns]', freq=None)
答案 0 :(得分:1)
我不清楚你的问题,但相信这是朝着正确方向迈出的一步。
def foo(date, periods, forward=True):
if isinstance(date, str):
date = pd.Timestamp(date).date()
dates = [date + relativedelta(date, months=n * (1 if forward else -1)) for n in range(1, periods +1)]
result = []
print dates
for date in dates:
month = date.month
iso_day = date.isoweekday()
if iso_day == 6:
date += dt.timedelta(days=2 if forward else -1)
elif iso_day == 7:
date += dt.timedelta(days=1 if forward else -2)
if date.month != month:
# Gone into next/preceding month. Roll back/forward.
date -= dt.timedelta(days=3 if forward else -3)
result.append(date)
return result
虽然未针对速度进行优化,但我相信以下功能将根据您的要求返回正确的值。
full-screen-loader
答案 1 :(得分:1)
你可能正在寻找这样的东西:
from pandas.tseries.offsets import Day, BDay
pd.date_range(start = '2012-01-01', periods = 6, freq = 'MS') + Day(22) + BDay(0)
Out[12]:
DatetimeIndex(['2012-01-23', '2012-02-23', '2012-03-23', '2012-04-23',
'2012-05-23', '2012-06-25'],
dtype='datetime64[ns]', freq=None)
Day(22)
添加22天的偏移量,BDay
负责营业日抵消(BDay(0)
需要最近的工作日)。
日期从30日开始有点困难。所以我必须为此编写一个函数。 (为了清晰的代码,它不允许自定义freq
参数。)
def my_business_date_range(day, **kwargs):
assert(isinstance(day, int) & (day > 0) & (day < 32))
rng0 = pd.date_range(freq = 'MS', **kwargs)
rng1 = rng0 + pd.tseries.offsets.Day(day-1) + pd.tseries.offsets.BDay(0)
# Correcting overflows:
overflow_idx, = np.nonzero(rng0.month != rng1.month)
if overflow_idx.size > 0:
# rng1 is not mutable
tmp = rng1.tolist()
bme = pd.tseries.offsets.BusinessMonthEnd(-1)
for i in overflow_idx:
tmp[i] = bme(rng1[i])
rng1 = pd.DatetimeIndex(tmp)
return rng1
my_business_date_range(30, start= '2012-01-01', periods = 6)
Out[13]:
DatetimeIndex(['2012-01-30', '2012-02-29', '2012-03-30', '2012-04-30',
'2012-05-30', '2012-06-29'],
dtype='datetime64[ns]', freq=None)
Pandas还有一个实验CustomBusinessMonth
and the like,但我无法使其发挥作用。