問題

假設我有一個數據框如下:

 df = pd.DataFrame({'Ending Date': [Timestamp('2019-12-08 00:00:00'), Timestamp('2019-12-08 00:00:00')], 'FName': ['Jon', 'Bob'], 'LName': ['Doe', 'Smith'], 'Starting Date': ['2019-09-29', '2019-09-29']})
 

   Ending Date FName  LName Starting Date
0  2019-12-07   Jon    Doe    2019-09-28
1  2019-12-07   Bob  Smith    2019-09-28
 

如您所見,終止日期列總是在啟動日期之前10周,但是,我有一個假期列表:

 holidays = pd.Series([Timestamp('2019-09-14 00:00:00'), Timestamp('2019-10-05 00:00:00'), Timestamp('2019-10-12 00:00:00'), Timestamp('2019-10-26 00:00:00'), Timestamp('2019-12-21 00:00:00'), Timestamp('2019-12-28 00:00:00'), Timestamp('2020-01-04 00:00:00'), Timestamp('2020-01-25 00:00:00'), Timestamp('2020-02-01 00:00:00'), Timestamp('2020-02-29 00:00:00'), Timestamp('2020-04-04 00:00:00'), Timestamp('2020-05-02 00:00:00')])
 

因此,我想“補償”假期,所以我想每個星期六得到在假期系列中計算的啟動日期和終止日期之間的範圍,並將n(計數)周新增到終止日期,如果增加的週數是假期,也補償他們,等等...

我試過了:

 df['Ending Date'] = df['Ending Date'] + pd.Timedelta(weeks=10 + pd.date_range(df['Starting Date'], df['Ending Date']).isin(holidays).sum())
 

但是錯誤:

 TypeError: Cannot convert input [0    2019-09-28
1    2019-09-28
Name: Starting Date, dtype: object] of type <class 'pandas.core.series.Series'> to Timestamp
 

提出。

所需輸出:

   Ending Date FName  LName Starting Date
0  2020-01-18   Jon    Doe    2019-09-28
1  2020-01-18   Bob  Smith    2019-09-28
 

  最佳答案

我假設啟動日期和結束日期都應該是datetime64[ns] 輸入.如果沒有,請用pd.to_datetime轉換它們.

我注意到你只使用星期六的日期,所以你的情況就像 我們有一個工作周,包括一個日曆周只有一個工作日, 也就是說只有星期六。

然後,為了完成任務,如果我們使用自定義業務,這是相當容易的 日曆,使用者定義假日。

首先定義CustomBusinessDay偏移量,包括您的hoilday列表:

 my_bday = pd.offsets.CustomBusinessDay(holidays=holidays, weekmask='Sat')
 

然後,計算 n 個工作日(實際上 – 還有幾個星期) 從給定的日期 dat,我們應該使用公式:dat + 10 * my_bday

所以在你的情況下(Starting Date列中的源資料和結果是 儲存在終止日期中),執行:

 df['Ending Date'] = df['Starting Date'].apply(lambda dat: dat + 10 * my_bday)
 

  相同標籤的其他問題

pythonpandasdatetimedate-range