Заменить дату на последний рабочий день - PullRequest
0 голосов
/ 29 мая 2020

Я пытаюсь заменить дату на последний рабочий день этого месяца и получаю сообщение

'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)

curr_date: 2020-01-31, 2020-02-29, 2020-03-31 Я хочу, чтобы 2020-02-29 был заменен на 2020-02-28, который является последним рабочий день в феврале. Спасибо

1 Ответ

0 голосов
/ 29 мая 2020

Начните с определения смещения до конца рабочего месяца:

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 , направление вращения - назад . Но передача назад здесь иногда откатывает дату еще день назад. Поэтому, чтобы избежать этого другого сдвига, этот параметр должен быть просто вперед .

А теперь, насколько быстрее это решение.

Использование % timeit Я измерил время выполнения предыдущего решения для выборки из 16 000 строк, получив 2,47 с .

Но время выполнения этого (второго) решения составляет 12,8 мс - в 190 раз быстрее .

Это намного лучшая скорость выполнения также является результатом того факта, что второе решение использует векторизованные операции вместо приложения функции в каждую строку.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...