我有一个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
答案 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'))