0

I'm having issues with an if statement and return the difference between two dates using a lambda function with the apply method. ['conus_days'] returns time/days in nanoseconds when the condition is true. What's wrong with my code?

us_bd = CustomBusinessDay(calendar=USFederalHolidayCalendar())

def get_conusdays(row):
   if row['Month']== row['conus_mth']:
       return forecast['Start Date'] - forecast['start_month'].apply(us_bd)
   else:
       return 0

forecast ['conus_days']= forecast.apply(lambda row: get_conusdays(row), axis=1)

print(forecast)

           Name      EID  Start Date   End Date      Country  year  Month  \
0  XX             123456 2019-08-01 2020-01-03            AF  2020      1   
1  XT.            3456789 2019-09-22 2020-02-16        Conus  2020      1   
2  MH.            456789 2019-12-05 2020-03-12        Conus   2020      1   
3  DR.            789456 2019-09-11 2020-03-04         IR     2020      1   
4  JR.            985756 2020-01-03 2020-05-06         GE     2020      1   

   days_in_month start_month  end_month  working_days  hours  conus_mth  \
0             31  2020-01-01 2020-01-31            21    372          8   
1             31  2020-01-01 2020-01-31            21    168          9   
2             31  2020-01-01 2020-01-31            21    168         12   
3             31  2020-01-01 2020-01-31            21    372          9   
4             31  2020-01-01 2020-01-31            21    310          1   

         cd                                         conus_days  
0 -154 days                                                  0  
1 -102 days                                                  0  
2  -28 days                                                  0  
3 -113 days                                                  0  
4    1 days  [-13305600000000000 nanoseconds, -881280000000...

gstukelj
  • 2,291
  • 1
  • 7
  • 20
  • 2
    I think you could just pass `get_conusdays` to `apply` directly, like this: `forecast.apply(get_conusdays, axis=1)`. – gstukelj Dec 24 '19 at 13:16

1 Answers1

0

This is because the return of the get_conusdays function is one series and one value(0). You need to unify your return output with a series or value.

you can try like this:

1. np.where

forecast ['conus_days'] = np.where(forecast['Month']==forecast["conus_mth"],
                                   forecast['Start Date'] - forecast['start_month'].apply(us_bd),
                                   0)

added.

start_date = pd.to_datetime('2020-01-03')
end_date = pd.to_datetime('2020-01-20')
print(len(pd.DatetimeIndex(start=start_date,end=end_date, freq=us_bd)))

>>> 12  #skip US holidays as well as weekends

so,

forecast ['conus_days'] = np.where(forecast['Month']==forecast["conus_mth"],
                                   forecast.apply(lambda row : len(pd.DatetimeIndex(start=row['end_moth'],end=row['End Date'], freq=us_bd)), axis=1),
                                   0)

same problem : Most recent previous business day in Python

2. apply(your method)

def get_conusdays(row):
   if row['Month']== row['conus_mth']:
       return row['Start Date'] - row['start_month'].apply(us_bd)
   else:
       return 0
forecast['conus_days']= forecast.apply(lambda row: get_conusdays(row), axis=1)

If you don't know the CustomBusinessDay exactly and you don't need to apply it to the series, you should do it this way(each row).

yganalyst
  • 494
  • 2
  • 7
  • yganalyst - in method 1 (np.where) do you know why custombusinessday does not offset weekends in certain occasions. for example if you take the example above and replace it with forecast['end_month] - forecast['End Date'].apply(us_bd), you will get number of days between those two time periods minus the holiday but, not the weekends. How can I correct this? – German Portes Jan 30 '20 at 18:06
  • sorry for the answer is late. i was updated my answer. I hope it helps and tell me if you need more help. – yganalyst Jan 31 '20 at 11:09