【问题标题】:How to create a Series of datetime values for the nth calendar of the month for this year?如何为今年每月的第 n 个日历创建一系列日期时间值?
【发布时间】:2021-07-08 03:26:34
【问题描述】:

我想为当年每个月的第 N 个日历日创建一个 [返回] 熊猫系列日期时间值的 [函数]。一个额外的皱纹是,如果它恰好落在周末,我还需要它是前一个工作日。奖励将是检查已知的假期。

例如,我希望 [工作日早于或等于] 月 14 日的输出如下所示

0    2021-01-14
1    2021-02-12
2    2021-03-12
3    2021-04-14
4    2021-05-14
5    2021-06-14
6    2021-07-14
7    2021-08-13
8    2021-09-14
9    2021-10-14
10   2021-11-12
11   2021-12-14

我尝试使用 pd.date_range() 和 pd.bdate_range() 并没有得到想要的结果。示例:

pd.date_range("2021-01-14","2021-12-14", periods=12)

>> DatetimeIndex(['2021-01-14 00:00:00',
           '2021-02-13 08:43:38.181818182',
           '2021-03-15 17:27:16.363636364',
           '2021-04-15 02:10:54.545454546',
           '2021-05-15 10:54:32.727272728',
           '2021-06-14 19:38:10.909090910',
           '2021-07-15 04:21:49.090909092',
           '2021-08-14 13:05:27.272727272',
           '2021-09-13 21:49:05.454545456',
           '2021-10-14 06:32:43.636363640',
           '2021-11-13 15:16:21.818181820',
                     '2021-12-14 00:00:00'],
          dtype='datetime64[ns]', freq=None)>>

此外,这需要知道作为开始和结束的第一个月和最后一个月的日子。使用 pd.bdate_range() 进行的类似测试主要导致错误。

【问题讨论】:

  • # 每月第 14 个日历日 pd.date_range('2021-01-01', period=12, freq='MS') + pd.DateOffset(days=13)

标签: python-3.x pandas


【解决方案1】:

您可以使用月份开始,然后添加一个 timedelta 来获取您想要的日期。因此,对于您的示例,它将是:

pd.date_range(start=pd.Timestamp("2020-12-14"), periods=12, freq='MS') + pd.Timedelta(days=13)

输出:

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

转到前一个工作日使用(请参阅:Pandas offset DatetimeIndex to next business if date is not a business dayMost recent previous business day in Python):

(pd.date_range(start=pd.Timestamp("2021-06-04"), periods=12, freq='MS') + pd.Timedelta(days=4)).map(lambda x: x - pd.tseries.offsets.BDay())

输出:

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

【讨论】:

  • 我以为是奖励,现在加了,谢谢
  • 这也包含所有必需的信息,谢谢。
【解决方案2】:

Pandas Date Range Monthly on Specific Day of Month 类似的方法,但减去Bday 以获得前一个营业日。同样从上一年的 12/31 开始,获取当年的所有值:

def get_date_range(day_of_month, year=pd.Timestamp.now().year):
    return (
            pd.date_range(start=pd.Timestamp(year=year - 1, month=12, day=31),
                          periods=12, freq='MS') +
            pd.Timedelta(days=day_of_month) -
            pd.tseries.offsets.BDay()
    )

使用年份:

get_date_range(14)
DatetimeIndex(['2021-01-14', '2021-02-12', '2021-03-12', '2021-04-14',
               '2021-05-14', '2021-06-14', '2021-07-14', '2021-08-13',
               '2021-09-14', '2021-10-14', '2021-11-12', '2021-12-14'],
              dtype='datetime64[ns]', freq=None)

或者再过一年:

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

有假期(这是非矢量化的,因此会引发PerformanceWarning):

import pandas as pd
from pandas.tseries.holiday import USFederalHolidayCalendar
from pandas.tseries.offsets import CustomBusinessDay

bday_us = CustomBusinessDay(calendar=USFederalHolidayCalendar())


def get_date_range(day_of_month, year=pd.Timestamp.now().year):
    return (
            pd.date_range(start=pd.Timestamp(year=year - 1, month=12, day=31),
                          periods=12, freq='MS') +
            pd.Timedelta(days=day_of_month) -
            bday_us
    )
get_date_range(25)
DatetimeIndex(['2021-01-25', '2021-02-25', '2021-03-25', '2021-04-23',
               '2021-05-25', '2021-06-25', '2021-07-23', '2021-08-25',
               '2021-09-24', '2021-10-25', '2021-11-24', '2021-12-23'],
              dtype='datetime64[ns]', freq=None)

【讨论】:

  • 非常感谢,这正是我想要的!我会投票,但我是新手。
猜你喜欢
  • 1970-01-01
  • 2019-07-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-15
  • 2010-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多