【问题标题】:Pandas date_range for specific day of month [duplicate]每月特定日期的熊猫日期范围[重复]
【发布时间】:2018-08-17 17:31:57
【问题描述】:

我想得到一个日期范围,其中每个月的日期都与开始日期相同,例如,如果开始日期是 2018-05-16,我想得到 ['2018-09-15, 2018 -10-15,...]

我在 Python3 中有以下代码:

(pd.date_range(start=date, periods=12, freq='M') \
+ pd.DateOffset(days=datetime.strptime(date, '%Y-%m-%d').day)).strftime('%d-%m-%Y')

当月份的日期小于 29 时,它可以正常工作,例如 date = '2018-08-31' 输出:

 array(['01-10-2018', '31-10-2018', '01-12-2018',
'31-12-2018', '31-01-2019', '03-03-2019', 
'31-03-2019', '01-05-2019', '31-05-2019', 
'01-07-2019', '31-07-2019', '31-08-2019'], dtype='|S10')

但是,我希望输出是:

array(['30-09-2018', '31-10-2018', '30-11-2018', 
'31-12-2018', '31-01-2019', '28-02-2019', 
'31-03-2019', '30-04-2019', '31-05-2019', 
'30-06-2019', '31-07-2019', '31-08-2019'], dtype='|S10')

【问题讨论】:

  • 所以你想从当前月份的下一个月开始获取该月的最后一天?
  • Sa'haido,我想得到每个月的起始日期的同月天,除非对应的月份没有这样的天。例如。如果起始月份的日期是 30,我希望每个月的第 30 天,除了在 2 月,我想要闰年的 28 或 29。
  • @McNulty,请编辑您的问题以反映您刚才在评论中所说的内容,这不清楚!
  • @McNulty,也请在下面查看我的更新答案!我希望这能满足您的需求!

标签: pandas


【解决方案1】:

更新答案:

对于在开始日期(或该月的最后一个可行日期,考虑到不同的月份天数和闰年)中给出的每月特定日期的每月频率范围内,此功能应该有效,至少每月频率:

import pandas as pd

def month_range_day(start=None, periods=None):
    start_date = pd.Timestamp(start).date()
    month_range = pd.date_range(start=start_date, periods=periods, freq='M')
    month_day = month_range.day.values
    month_day[start_date.day < month_day] = start_date.day
    return pd.to_datetime(month_range.year*10000+month_range.month*100+month_day, format='%Y%m%d')

示例 1

start_date = '2020-01-31'
month_range_day(start=start_date, periods=12)

输出:

DatetimeIndex(['2020-01-31', '2020-02-29', '2020-03-31', '2020-04-30',
               '2020-05-31', '2020-06-30', '2020-07-31', '2020-08-31',
               '2020-09-30', '2020-10-31', '2020-11-30', '2020-12-31'],
              dtype='datetime64[ns]', freq=None) 

示例 2:

start_date = '2019-01-29'
month_range_day(start=start_date, periods=12)

输出:

DatetimeIndex(['2019-01-29', '2019-02-28', '2019-03-29', '2019-04-29',
               '2019-05-29', '2019-06-29', '2019-07-29', '2019-08-29',
               '2019-09-29', '2019-10-29', '2019-11-29', '2019-12-29'],
              dtype='datetime64[ns]', freq=None)

上一个答案:

假设您只是想要月末频率,则无需使用pd.DateOffset

import pandas as pd
start_date = '2018-09-01'
pd.date_range(start=start_date, periods=12, freq='M').strftime('%d-%m-%Y')

输出:

Index(['30-09-2018', '31-10-2018', '30-11-2018', '31-12-2018', '31-01-2019',
       '28-02-2019', '31-03-2019', '30-04-2019', '31-05-2019', '30-06-2019',
       '31-07-2019', '31-08-2019'],
      dtype='object')

更多详情,请查看pandas 中的offset aliases。如有必要,应该从这里直接更改数据格式和类型。

【讨论】:

  • 感谢 mloning 抽出宝贵时间。但我想要的是每个月都与我在开始日期使用的月份完全相同,只有当相应的月份没有这样的日子时,我才想要月底的日子。例如。如果开始日期是 '2018-08-29',我想得到的输出是: ['29-09-2018', '29-10-2011', ...., '28-02-2018' , ...., '29-08-2018']。对不起我的英语。
  • 非常感谢您抽出宝贵的时间,mloning。您的代码完全按照我的意愿解决了我的问题。
  • @McNulty,太好了!那么请接受答案。
【解决方案2】:

为什么不直接删除第 0 个元素?

date = '2018-08-31'
(pd.date_range(
    start = date,
    periods = 12+1,
    freq ='M')
).strftime('%d-%m-%Y')[1:]

输出:

Index(['30-09-2018', '31-10-2018', '30-11-2018', '31-12-2018', '31-01-2019',
       '28-02-2019', '31-03-2019', '30-04-2019', '31-05-2019', '30-06-2019',
       '31-07-2019', '31-08-2019'],
  dtype='object')

【讨论】:

  • 这似乎并没有带来任何新的东西,而且相当混乱,因为您只需将开始日期向后移动一个月,然后选择所有每月频率而不选择第一个频率。
  • 感谢 Dmitry Mottl,感谢您的回答和您的宝贵时间。我不想让月底一天看到我上面的评论。
猜你喜欢
  • 1970-01-01
  • 2017-02-23
  • 2018-07-13
  • 2018-11-24
  • 1970-01-01
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
  • 2013-03-09
相关资源
最近更新 更多