Random Date Each Month After the Second Week

Viewed 57

I am trying to generate a list of random dates from now until the year 2040. The calendar is based off the U.S Calendar. The expected result should be one date from each month. The constraints being that the random date must:

  • Be a U.S business workday (Mon-Fri)

  • Not be a U.S holiday

  • Be after the second week of the month

Expected output. something like:

2019-06-26
2019-07-16
2019-08-23
2019-09-19
2019-10-14
...
2039-12-22

Below is what I've tried. I can meet all three constraints - but just need a way to pick randomly one day out of each month.

import datetime 
import pandas as pd
from pandas.tseries.holiday import USFederalHolidayCalendar as calendar


# create a date range of all workdays from 6-18-19 to end of 2039
dates = pd.bdate_range(start='2019-06-18', end='2039-12-31', freq='B')

# put into a dataframe
df = pd.DataFrame(dates, columns=['Date'])

# calculate the week number
df['Week_Number'] = df['Date'].apply(lambda x: (x.day-1)//7+1)

# create a list of holidays 
cal = calendar()
holiday_list = cal.holidays(start='2019-06-18', end='2039-12-31')

# Boolean if Date is a holiday
df['Holiday'] = df['Date'].isin(holiday_list)

# filter out Holidays and dates that are before the third week.
df.loc[(df['Week_Number']> 2) & (df['Holiday'] == False)]

I'm just missing the last piece - How do I return one day for each month out of this result?

Or perhaps there is an easier way all together that doesn't use what I've tried thus far.

1 Answers

IIUC, you can do:

#assign last line to a variable
m=df.loc[(df['Week_Number']> 2) & (df['Holiday'] == False),'Date'].to_frame() 

Then use sample() under groupby:

(m.groupby([m.Date.dt.month,m.Date.dt.year]).apply(lambda x: x.sample(1))
                                                  .reset_index(drop=True))
Related