将日期替换为最后一个工作日

时间:2020-05-29 16:27:31

标签: python pandas

我正在尝试用该月的最后一个工作日替换日期并获取消息

'TypeError:无效的“ to_replace”类型:“ str”

代码:

df['curr_date'] = pd.to_datetime(df['curr_date'])
df['curr_date'] = df['curr_date'].replace('curr_date',df.loc[df.curr_date.isin(df.curr_date + pd.offsets.BMonthEnd(1))],inplace = True)

更新日期:2020-01-31、2020-02-29、2020-03-31 我希望将2020-02-29替换为2020-02-28,这是2月的最后一个工作日。谢谢

1 个答案:

答案 0 :(得分:0)

从定义到工作月末的偏移量开始:

offs = pd.offsets.BMonthEnd(0)

然后定义一个函数来计算当前日期的最后一个工作日:

def dateCorr(dat : pd.Timestamp) -> pd.Timestamp:
    dFwd = offs.rollforward(dat)
    return dFwd if dFwd.month == dat.month else offs.rollback(dat)

出于测试目的,将“更正”的日期另存为新列:

df['LastBDay'] = df.curr_date.apply(dateCorr)

因此您将能够比较源日期和新日期。

当然,在最终版本的代码中,将 LastBDay 替换为 curr_date ,以覆盖现有列。

另一个更快的解决方案

您可能知道, Numpy 的运行速度比 Pandas 快得多,因此 我寻找了完全基于 Numpy

来完成任务的方法。

结果是我找到了更快的解决方案:

df['LastBDay'] = np.busday_offset(
    df.curr_date.values.astype('M8[M]') + np.timedelta64(1, 'M'), -1, roll='forward')

步骤:

  • df.curr_date.values.astype('M8[M]')-将 curr_date 转换为带有 分辨率。
  • + np.timedelta64(1, 'M')-将这个日期提前一个月。
  • np.busday_offset(-查找工作日,从第一个开始 争论。
  • -1-1天前。
  • roll='forward'-这是一个棘手的细节。由于偏移量为 -1 , 滚动方向为后退。但是在这里传递 back 可以滚动日期 有时另一天。因此,为了避免这种转变, 此参数必须为 forward

现在这个解决方案有多快。

使用%timeit 我测量了先前解决方案的执行时间 对于16,000行的样本,得到 2.47 s

但是此(第二个)解决方案的执行时间为 12.8 ms - 190次

更快的执行速度还来自以下事实: 第二种解决方案使用 vectorized 操作而不是应用程序 每行的功能。