Pandas: Количество месяцев между двумя датами
У меня возникла проблема, которая, как я думал, должна быть простой, но то, что я видел, представляет собой техники, которые требуют итерации по полям дат в dataframe, чтобы определить разницу между двумя датами. Я с этим испытываю трудности. Я знаком с функцией DATEDIFF в MSSQL, и думал, что в Pandas для работы с datetime есть что-то подобное. Возможно, такое и есть, но я этого не нахожу.
Существует ли "пандовский" способ определения количества полных месяцев в виде целого числа между двумя датами (datetime) без необходимости итерации? Учитывайте, что в potentially может быть миллионы строк, поэтому производительность является важным аспектом.
Даты являются объектами datetime, а результат должен выглядеть следующим образом - новый столбец "Months":
Date1 Date2 Months
2016-04-07 2017-02-01 11
2017-02-01 2017-03-05 1
5 ответ(ов)
Вот очень простой ответ, мой друг:
df['nb_months'] = (df.date2 - df.date1) / np.timedelta64(1, 'M')
А теперь:
df['nb_months'] = df['nb_months'].astype(int)
Этот код вычисляет количество месяцев между двумя датами в столбцах date1
и date2
и преобразует полученное значение в тип int
.
Альтернативное, возможно, более элегантное решение заключается в следующем:
delta = df.Date2.dt.to_period('M') - df.Date1.dt.to_period('M')
Этот подход позволяет избежать ошибок округления.
Начиная с версии Pandas 0.24, данное выражение возвращает смещение, которое можно преобразовать в целое число с помощью следующей команды:
delta.apply(lambda x: x.n)
Таким образом, вы сможете получить количество месяцев между двумя датами без потерь точности.
Вы можете использовать метод assign
для добавления нового столбца в DataFrame, который будет вычислять разницу в месяцах между двумя датами. В вашем случае это можно сделать следующим образом:
df.assign(
Months=
(df.Date2.dt.year - df.Date1.dt.year) * 12 +
(df.Date2.dt.month - df.Date1.dt.month)
)
В результате у вас получится DataFrame с новым столбцом Months
, который содержит количество полных месяцев между датами в столбцах Date1
и Date2
. Например:
Date1 Date2 Months
0 2016-04-07 2017-02-01 10
1 2017-02-01 2017-03-05 1
Здесь, для первой строки, разница составляет 10 месяцев, а для второй — 1 месяц.
Попробуйте сделать так:
df['Months'] = df['Date2'].dt.to_period('M').astype(int) - df['Date1'].dt.to_period('M').astype('int64')
df
# Вывод:
# Date1 Date2 Months
# 0 2016-04-07 2017-02-01 10
# 1 2017-02-01 2017-03-05 1
Этот код рассчитывает разницу в месяцах между двумя датами: Date1
и Date2
. Мы используем метод to_period('M')
, чтобы преобразовать даты в месяцы, а затем вычитаем одно значение из другого. Результат сохраняется в новом столбце Months
.
Маленькое дополнение к ответу @pberkes. Если вы хотите получить результат в целочисленном формате, а НЕ как pandas._libs.tslibs.offsets.MonthEnd
, просто добавьте .n
в приведённый выше код.
(pd.to_datetime('today').to_period('M') - pd.to_datetime('2020-01-01').to_period('M')).n
# [Out]:
# 7
Как изменить порядок столбцов в DataFrame?
Установить значение для конкретной ячейки в DataFrame pandas с использованием индекса
Выбор строки из pandas Series/DataFrame по целочисленному индексу
Преобразование строки даты JSON в datetime в Python
Получить все ключи из объекта GroupBy в Pandas