Pandas在特定日期创建日期范围

2024-03-29 02:19:38 发布

您现在位置:Python中文网/ 问答频道 /正文

我想创建一个列表(或数组或其他任何东西),每个月间隔一个给定数量的日期。在

基本上我想要的就是这个

>>>some_function(start_date=date(2005, 5, 14), periods=4, freq='M')
['2005-05-14', '2005-06-14', '2005-07-14', '2005-08-14']

如果月初日快到月底了,我要这个

^{pr2}$

我知道pandas date_range函数,但是它会产生这个函数

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的日期接近该月的最后一天时,这会造成麻烦。在

有没有人知道有一个函数会产生这个函数,或者上面概述的方法是唯一的方法吗?在


Tags: 方法函数pandas列表数量date间隔range
3条回答

我认为你所追求的行为是,你想要一个日期范围,所有的日期都是在同一天的一个月作为你的开始日期,除了使用一个月的最后一天,在一个月里有较少的天数。在

您可以使用pandas.DateOffset(months=1, day=day_of_month)作为freq参数,其中day_of_month是您希望每个日期在哪个月的哪一天。对于最后一天小于day_of_month的月份,这将自动使用该月的最后一天。在

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>')

这应该行得通。add_months函数通过How to increment datetime by custom months in python without using library中的@davewbb。在

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)]

我精心制作了以下内容:

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

相关问题 更多 >