首页 文章

“在Pandas工作日后修改”

提问于
浏览
3

如何在Pandas中有效实施“修改后的”工作日付款规则的矢量化版本?

Background

在财务方面,通常情况下固定收益优惠券是在"modified following"基础上支付的,也就是说,如果优惠券日期是在周末或假日,则在下一个工作日支付,除非下一个工作日落入下一个工作日日历月,在这种情况下,我们会回到最近的工作日 .

April 2017       
Su Mo Tu We Th Fr Sa  
                   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

2017年4月就是一个很好的例子 . 如果付款在星期六15日付款,它将被转移到星期一17日 . 然而,如果它在两周后的星期六29日落下,它将被倒退到星期五28日(因为下一个星期一将在5月) .

我需要一次为成千上万个日期做这个,所以我希望它可以被矢量化并且如果可能的话大熊猫效率(也就是说,我想避免只通过if-then-else运行每个日期) . 因此,给定一个日期向量,它将检查Sat / Sun的哪个下降并自动应用规则,输出“修改后的”日期的向量 .

1 回答

  • 2

    如果您对熊猫解决方案感兴趣,这是一个开始:

    import pandas as pd
    from pandas.tseries.holiday import USFederalHolidayCalendar
    from pandas.tseries.offsets import CustomBusinessDay
    
    BDayUS = CustomBusinessDay(calendar=USFederalHolidayCalendar())       
    
    def is_weekday(dates):
        return ~dates.weekday_name.isin(['Saturday', 'Sunday'])
    
    def in_next_month(dates1, dates2):
        return dates1.month == dates2.month - 1
    
    def next_bus_day(dates):
        fwd = dates + BDayUS(1)
        return fwd.where(~in_next_month(dates, fwd), dates - BDayUS(1))
    
    def payment_day(dates):
        return dates.where(is_weekday(dates), next_bus_day(dates))
    

    2017年4月:

    dates = pd.date_range('4/1/2017', '4/30/2017')
    
    payment_day(dates)
    # DatetimeIndex(['2017-04-03', '2017-04-03', '2017-04-03', '2017-04-04',
    #                '2017-04-05', '2017-04-06', '2017-04-07', '2017-04-10',
    #                '2017-04-10', '2017-04-10', '2017-04-11', '2017-04-12',
    #                '2017-04-13', '2017-04-14', '2017-04-17', '2017-04-17',
    #                '2017-04-17', '2017-04-18', '2017-04-19', '2017-04-20',
    #                '2017-04-21', '2017-04-24', '2017-04-24', '2017-04-24',
    #                '2017-04-25', '2017-04-26', '2017-04-27', '2017-04-28',
    #                '2017-04-28', '2017-04-28'],
    #               dtype='datetime64[ns]', freq='D')
    
    payment_day(dates).weekday_name
    # Index(['Monday', 'Monday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
    #        'Friday', 'Monday', 'Monday', 'Monday', 'Tuesday', 'Wednesday',
    #        'Thursday', 'Friday', 'Monday', 'Monday', 'Monday', 'Tuesday',
    #        'Wednesday', 'Thursday', 'Friday', 'Monday', 'Monday', 'Monday',
    #        'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Friday', 'Friday'],
    #       dtype='object')
    

    另见:文档中的Custom Business Day . 请对此进行压力测试;我大多只是使用默认的BDay,我不确定联邦假期是否与纽约证券交易所市场关闭完美契合 .

相关问题