我希望将自定义工作日偏移量列添加到日期列:
>> import pandas as pd
>> from pandas.tseries.offsets import CustomBusinessDay
>> df = pd.DataFrame({'ship_date_et': ['2018-10-01' for x in range(10)], 'offset': [x for x in range(10)]})
>> df['offset'] = pd.to_timedelta(df['offset'], unit='D')
>> df['ship_date_et'] = pd.to_datetime(df['ship_date_et'])
>> df.dtypes
offset timedelta64[ns]
ship_date_et datetime64[ns]
>> df
offset ship_date_et
0 0 days 2018-10-01
1 1 days 2018-10-01
2 2 days 2018-10-01
3 3 days 2018-10-01
4 4 days 2018-10-01
5 5 days 2018-10-01
6 6 days 2018-10-01
7 7 days 2018-10-01
8 8 days 2018-10-01
9 9 days 2018-10-01
>> holidays = ['2018-10-10'] # '2018-10-10' just a made-up holiday
>> cdays = CustomBusinessDay(holidays=holidays, weekmask='Mon Tue Wed Thu Fri')
>> df['ship_date_et'] + df['offset'].apply(cdays)
0 2018-10-02
1 2018-10-03
2 2018-10-04
3 2018-10-05
4 2018-10-06
5 2018-10-07
6 2018-10-08
7 2018-10-09
8 2018-10-10
9 2018-10-11
dtype: datetime64[ns]
这是疯狂的错误。周末(2018-10-06 和 2018-10-07(不计算(熊猫文档说CDay
包含周末(。这与我只定义了 2weekmask
天(周一和周二(无关。
我真的很困惑和沮丧,因为这适用于正常BDay
:
>> df['ship_date_et'] + df['offset'].dt.days.apply(BDay) # Doing dt.days to get integer for BDay since we defined df['offset'] as a `timedelta`
0 2018-10-01
1 2018-10-02
2 2018-10-03
3 2018-10-04
4 2018-10-05
5 2018-10-08
6 2018-10-09
7 2018-10-10
8 2018-10-11
9 2018-10-12
我想要的结果:
>> df['ship_date_et'] + df['offset'].apply(cdays)
0 2018-10-01
1 2018-10-02
2 2018-10-03
3 2018-10-04
4 2018-10-05
5 2018-10-08
6 2018-10-09
7 2018-10-11
8 2018-10-12
9 2018-10-15
我已经通读了文档(numpybusday
和 Pandas(并搜索了互联网,例如这里和这里(,但找不到正在发生的事情的原因。最令人担忧的部分是我的cdays
定义,在index=0
是0 days
,但结果返回我的ship_date_et
天 + 1。
当然,使用apply
和以下方面也存在问题:
PerformanceWarning: Adding/subtracting array of DateOffsets to Series not vectorized "Series not vectorized"
熊猫给。
我将不胜感激任何反馈或意见。谢谢!
看起来您只将 cdays 应用于偏移量而不是 ship_date+偏移量。
(df['ship_date_et'] + df['offset']).apply(cdays)
@dlstadther,虽然你的答案确实给了期偏移量,但它并没有将周末或节假日视为零。我认为这与我将df['offset']
实现为type timedelta
有关。这导致:
>> (df['ship_date_et'] + df['offset']).apply(cdays)
0 2018-10-02
1 2018-10-03
2 2018-10-04
3 2018-10-05
4 2018-10-08
5 2018-10-08
6 2018-10-08
7 2018-10-09
8 2018-10-11
9 2018-10-11
dtype: datetime64[ns]
它没有将周末和节假日视为零,不存在,无论你想怎么想,并在它们之后继续计数器。我会说那是由于我无法提出一个好问题。
我的回答:
稍作睡眠和思考:
>> df['new'] = df['ship_date_et'] + df['offset'].dt.days*cdays
是我一直在寻找的。
>> df
offset ship_date_et new
0 0 days 2018-10-01 2018-10-01
1 1 days 2018-10-01 2018-10-02
2 2 days 2018-10-01 2018-10-03
3 3 days 2018-10-01 2018-10-04
4 4 days 2018-10-01 2018-10-05
5 5 days 2018-10-01 2018-10-08
6 6 days 2018-10-01 2018-10-09
7 7 days 2018-10-01 2018-10-11
8 8 days 2018-10-01 2018-10-12
9 9 days 2018-10-01 2018-10-15
在此示例中跳过"假期"和周末,计数器会像BDay
一样继续经过它们。
如果df['offset']
是类型int
,则不必执行.dt.days
。