Pandas create date range at certain dates
我想每月创建一个给定日期数量的列表(或数组或其他内容)。
基本上我想要的是这个
1 2 | >>>some_function(start_date=date(2005, 5, 14), periods=4, freq='M') ['2005-05-14', '2005-06-14', '2005-07-14', '2005-08-14'] |
如果startmonth的日期接近月末,我想要这个
1 2 | >>>some_function(start_date=date(2007, 12, 31), periods=4, freq='M') ['2007-12-31', '2008-01-31', '2008-02-29', '2008-03-31'] |
号
我知道熊猫的日期范围函数,但是它产生了这个
1 2 3 | pd.date_range(date(2005, 5, 14), periods=4, freq='M') Out[1]: DatetimeIndex(['2005-05-31', '2005-06-30', '2005-07-31', '2005-08-31'], dtype='datetime64[ns]', freq='M') |
也就是说,它将月底设置为日。这不是我想要的。
显然,这可以通过迭代周期数生成,但当startmonth的日期接近该月的最后一天时,这会造成麻烦。
有人知道产生这个的函数吗,或者上面概述的方法是唯一的方法吗?
我精心制作了以下内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | from datetime import datetime from datetime import timedelta def next_month_generator(d): while True: if d.month == 12: # on Dec, need to change year d = d.replace(year=d.year+1, month=1) else: try: # get next month, same date d = d.replace(month=d.month+1) except ValueError: # get next month, last months date d = date(year=d.year, month=d.month+2, day=1) - timedelta(days=1) yield d start_date=date(2017, 01, 31) nm = next_month_generator(start_date) for _ in range(13): print(nm.next()) >> 2017-02-28 >> 2017-03-28 >> 2017-04-28 >> 2017-05-28 >> 2017-06-28 >> 2017-07-28 >> 2017-08-28 >> 2017-09-28 >> 2017-10-28 >> 2017-11-28 >> 2017-12-28 >> 2018-01-28 >> 2018-02-28 |
号
这应该有效。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 | import datetime import calendar start_date = '2018-02-02' def add_months(sourcedate, months): month = sourcedate.month - 1 + months year = sourcedate.year + month // 12 month = month % 12 + 1 day = min(sourcedate.day, calendar.monthrange(year, month)[1]) return datetime.date(year, month, day) def range_of_months(sourcedate, months): return [add_months(sourcedate, m) for m in range(months+1)] start = datetime.date.today() range_of_months(start, 5) # [datetime.date(2018, 2, 2), # datetime.date(2018, 3, 2), # datetime.date(2018, 4, 2), # datetime.date(2018, 5, 2), # datetime.date(2018, 6, 2), # datetime.date(2018, 7, 2)] |
我认为你所追求的行为是,你想要一个日期范围,其中所有的日期都与你的开始日期在同一个月的同一天,除了将月的最后一天用于月份中天数较少的月份。
你可以用
1 2 3 4 5 | In [68]: pandas.date_range('2005-05-14', periods=4, freq=pandas.DateOffset(months=1, day=14)) Out[68]: DatetimeIndex(['2005-05-14', '2005-06-14', '2005-07-14', '2005-08-14'], dtype='datetime64[ns]', freq='<DateOffset: day=14, months=1>') In [69]: pandas.date_range('2007-12-31', periods=4, freq=pandas.DateOffset(months=1, day=31)) Out[69]: DatetimeIndex(['2007-12-31', '2008-01-31', '2008-02-29', '2008-03-31'], dtype='datetime64[ns]', freq='<DateOffset: day=31, months=1>') |