Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/41.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 创建具有任意开始日期的月度时间序列_Python_Pandas_Python Datetime - Fatal编程技术网

Python 创建具有任意开始日期的月度时间序列

Python 创建具有任意开始日期的月度时间序列,python,pandas,python-datetime,Python,Pandas,Python Datetime,使用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',

使用
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-04-30”有几个月的时间。我希望看到:

DatetimeIndex(['2012-01-30', '2012-02-29', '2012-03-30', '2012-04-30'],
              dtype='datetime64[ns]', freq=None)

我不清楚你的问题,但我相信这是一个正确的方向

start = '2012-04-23'
end = '2013-01-23'

>>> pd.DatetimeIndex([pd.datetime(ts.year, ts.month, int(end.split("-")[-1])) 
                      for ts in pd.date_range(start, end, 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)
虽然没有针对速度进行优化,但我相信以下函数将根据您的要求返回正确的值

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

您可能正在寻找以下内容:

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_范围(天,**kwargs):
断言(isinstance(天,整数)和(天>0)和(天<32))
rng0=pd.日期\范围(频率='MS',**kwargs)
rng1=rng0+pd.tseries.offset.Day(第1天)+pd.tseries.offset.BDay(0)
#纠正溢出:
溢出\u idx,=np.非零(rng0.month!=rng1.month)
如果溢出_idx.size>0:
#rng1是不可变的
tmp=rng1.tolist()
bme=pd.tseries.offset.BusinessMonthEnd(-1)
对于溢出_idx中的i:
tmp[i]=bme(rng1[i])
rng1=pd.DatetimeIndex(tmp)
返回rng1
我的业务日期范围(30,开始日期='2012-01-01',期间=6)
出[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)

熊猫队也有一个实验项目,但我无法让它工作。

我不明白。您刚才问的似乎不是您希望看到的,即,top DatetimeIndex是该月的最后一个工作日,可以追溯到时间。@Alexander这是因为我不知道将什么作为
freq
参数。我不想每天生产,我相信这是默认的。所以今天是5月6日(已经?!?…)。3月6日是星期天。你想看什么?三月四日(星期五)?@亚历山大:是的。但我在问题中没有具体说明这一点。我不想把它复杂化。这对于我在本例中使用的特定日期集肯定有效。我已经有了一个健壮的,如果是复杂的解决方案。我想征求其他意见,这样我可能会有一个更清晰的答案。在我的问题中,我将继续补充一些评论。“BM”似乎不是有效的选项。如果今天是2016年6月1日(星期三)。2016-05-01是星期天,你想看2016-04-28(星期五)吗?这是一个很好的问题。我必须选择2016-05-02。我的解决方案包括一次回滚一个月,并考虑多个因素做出决策,例如,是否是周末,如果是,则回滚,除非该值下降到上个月(您的示例),否则回滚。原始日期是月末、营业月末还是开始日期,应该保留结束日期还是开始日期。您是选择结束日期并按照这些规则向后工作,还是选择开始日期并向前工作?这很好。对有趣的函数有很多很好的见解和参考。谢谢你的努力。
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)