如果日期不是工作日,Pandas会将DatetimeIndex偏移到下一个业务

时间:2015-09-29 02:54:03

标签: python pandas

我有一个DataFrame,它以该月的最后一天编入索引。有时这个日期是工作日,有时是周末。忽略假期,如果日期是在周末,我希望将日期偏移到下一个营业日期,如果已经在工作日,则保持结果不变。

一些示例数据将是

idx = df.index.copy()
wknds = (idx.weekday == 5) | (idx.weekday == 6)
idx2 = idx[~wknds]
idx2 = idx2.append(idx[wknds] + pd.datetools.BDay(1))
idx2 = idx2.order()
df.index = idx2
df

            A
2015-04-30  0
2015-06-01  0
2015-06-30  0

类似下面的工作,但如果有人有一个更直接的解决方案,我将不胜感激。

product

4 个答案:

答案 0 :(得分:3)

您可以添加0 * BDay()

from pandas.tseries.offsets import BDay
df.index = df.index.map(lambda x : x + 0*BDay())

如果有假期,您也可以使用带有CDay(日历)的假日日历。

答案 1 :(得分:1)

使用DataFrame.resample

一种更惯用的方法是将采样重新采样到工作日:

df.resample('B', label='right', closed='right').first().dropna() 

              A
2015-04-30  0.0
2015-06-01  0.0
2015-06-30  0.0

答案 2 :(得分:0)

您可以使用lambda函数映射索引,并将结果设置回索引。

df.index = df.index.map(lambda x: x if x.dayofweek < 5 else x + pd.DateOffset(7-x.dayofweek))

df
            A
2015-04-30  0
2015-06-01  0
2015-06-30  0

答案 3 :(得分:0)

也可以使用逻辑的变体:a) 给定输入日期 = 'inputdate',使用包含工作日输入的 pandas date_range 返回一个工作日;然后 b) 使用相同的方法前进一个工作日。为此,您使用 data_range 生成具有 2 个输入的向量,并选择最小值或最大值以返回适当的单个值。所以这可能如下所示:

a) 提前一天获取:

date_1b_bef = min(pd.date_range(start=inputdate, periods = 2, freq='-1B'))

b) 在“前一个工作日”之后获取工作日:

date_1b_aft = max(pd.date_range(start=date_1b_bef, periods = 2, freq='1B'))

或将 a) 代入 b) 得到一行:

date_1b_aft = max(pd.date_range(start=min(pd.date_range(start=inputdate, periods = 2, freq='-1B')), periods = 2, freq='1B'))

这也可以与 relativedelta 一起使用,以获取从 inputdate 偏移的某个日历周期后的工作日。例如:

a) 获取“输入日期”之前 1 个日历月的工作日(如果偏移日不是工作日,则使用“以下”约定):

date_1mbef_fol = max(pd.date_range(min(pd.date_range(start=inputdate + relativedelta(months=-1), periods = 2, freq='-1B')), periods = 2, freq = '1B'))

b) 获取“输入日期”之前 1 年的营业日(如果抵消日不是营业日,则使用“前面”约定):

date_1ybef_pre = min(pd.date_range(max(pd.date_range(start=inputdate + relativedelta(years=-1), periods = 2, freq='1B')), periods = 2, freq = '-1B'))