Add N Business Days to a Numpy datetime64 That's Not of Unit 'D'

2.5k views Asked by At

I'm trying to add business days to a long list of data that's currently formatted as datetime64 objects, but with type 'ns'.

As per the Numpy documentation, the busday_offset function only works on objects with units of 'D'. The functionality I want exists in Pandas, using 'BusiniessDayintseries.offsets`.

I could convert every date into a Pandas Timestamp, then add the offset, and then convert back, but that feels like more work than it should be.

Is there a way to directly add an arbitrary number of business days to a datetime64 object that has 'ns' units?

2

There are 2 answers

2
Ted Petrou On BEST ANSWER

It's much easier to use pandas but here is a numpy implementation. I initially create dates from pandas but that is not necessary. Any numpy dates with ns precision should work.

# get numpy only business days from pandas
pandas_dates = pd.date_range('today', periods=10, freq='B')
np_dates = pandas_dates.values

# Just get the day part
np_days = np_dates.astype('datetime64[D]')

# offset date using numpy and then convert back to ns precision.
# all seconds will be 0
np_day_offsets = np.busday_offset(np_days, 5).astype('datetime64[ns]')

# add back in nanoseconds
np_final = np_day_offsets + (np_dates - np_days)
0
piRSquared On
a = pd.date_range('2016-03-31', periods=5, freq='M').values
a

array(['2016-03-31T00:00:00.000000000', '2016-04-30T00:00:00.000000000',
       '2016-05-31T00:00:00.000000000', '2016-06-30T00:00:00.000000000',
       '2016-07-31T00:00:00.000000000'], dtype='datetime64[ns]')

pd.to_datetime(a) + pd.offsets.BusinessDay(8)

DatetimeIndex(['2016-04-12', '2016-05-11', '2016-06-10', '2016-07-12',
               '2016-08-10'],
              dtype='datetime64[ns]', freq=None)

Or if you want them in datetime64[ns]

(pd.to_datetime(a) + pd.offsets.BusinessDay(8)).values

array(['2016-04-12T00:00:00.000000000', '2016-05-11T00:00:00.000000000',
       '2016-06-10T00:00:00.000000000', '2016-07-12T00:00:00.000000000',
       '2016-08-10T00:00:00.000000000'], dtype='datetime64[ns]')