Чтобы упорядочить большой набор данных по месяцам, я пытаюсь преобразовать все фактические даты записи в конец месяца.
Я видел подобные вопросы и использовал код, который нашел, но он, похоже, не работает, если дата оказалась уже концом месяца (это приведет к тому, что вместо этого будет вычислен конец следующего месяца).
df['CalcEnd'] = pd.to_datetime(df['ActualDate'], format="%m/%d/%Y") + MonthEnd(1)
Это приводит к:
ActualDate CalcEnd
7/1/2019 7/31/2019
7/2/2019 7/31/2019
7/31/2019 8/31/2019
Третья запись должна вернуться 31.07.2009.
Я пытался использовать numpy, чтобы использовать CalcEnd только в том случае, если дата не является концом месяца, чтобы избежать этой проблемы, но по какой-то причине CalcEnd вывел странную серию чисел, если это не был уже конец месяца.
Конкретно я пытался:
def isMonthEnd(date):
return date + pd.offsets.MonthEnd(0) == date
df['EndCheck'] = isMonthEnd(pd.to_datetime(df['ActualDate'], format="%m/%d/%Y"))
df['CalcEnd'] = pd.to_datetime(df['ActualDate'], format="%m/%d/%Y") + MonthEnd(1)
df['End'] = np.where(df['EndCheck']==False, df['CalcEnd'], df['ActualDate'])
Когда EndCheck имеет значение False, вместо отображения 31.07.2009, он показывает 1564531200000000000.
Но когда это правда, он показывает ActualDate как 31.07.2009.
Любой совет по:
1) Как преобразовать все указанные даты в кадре данных в конец месяца, даже если данная дата уже является концом месяца; и
2) Почему оператор np.where не работает при попытке использовать вычисляемый столбец
.... будет принята с благодарностью!
Я смог найти обходной путь, просто записав фрейм данных в CSV и прочитав этот новый CSV обратно в фрейм данных перед созданием End; кажется, что это решает проблему с помощью оператора np.where, возвращающего 1564531200000000000. Однако я надеюсь, что есть более элегантное решение.
Спасибо!
2 ответа
Это поведение упоминается в документах:
Если п не 0 , если данная дата не на узловую точку, она привязывается к следующей (предыдущей) точки привязки , и переехал | п | -1 дополнительные шаги вперед или назад. , Если данная дата на опорной точке , он перемещается | п | указывает вперед или назад.
Вам не нужно np.where
. Исправить это просто. Если вы идете вперед, просто вычтите один день, прежде чем добавить якорь. Если вы идете назад, добавьте один день, прежде чем вычесть якорь
Вы идете вперед к MonthEnd
, так что просто вычтите один день перед добавлением якоря
df['CalcEnd'] = df['ActualDate'] - pd.offsets.Day() + pd.offsets.MonthEnd(1)
Out[370]:
ActualDate CalcEnd
0 2019-07-01 2019-07-31
1 2019-07-02 2019-07-31
2 2019-07-31 2019-07-31
Просто проверьте, находится ли дата в том же месяце, если вы добавляете один день и делаете смещение в зависимости от результата
def to_end_of_month(date):
if (date + pd.offsets.Day(1)).month == date.month:
return date + pd.offsets.MonthEnd(1)
else:
return date + pd.offsets.MonthEnd(0)
df['CalcEnd'] = df['ActualDate'].apply(to_end_of_month)
Результат
ActualDate CalcEnd
0 2019-07-01 2019-07-31
1 2019-07-02 2019-07-31
2 2019-07-31 2019-07-31
Похожие вопросы
Новые вопросы
python-3.x
НЕ ИСПОЛЬЗУЙТЕ, ЕСЛИ ВАШ ВОПРОС ТОЛЬКО ДЛЯ PYTHON 3. Всегда используйте вместе со стандартным тегом [python].