Зберігайте лише частину дати під час використання pandas.to_datetime


206

Я використовую pandas.to_datetimeдля розбору дат у своїх даних. Панди за замовчуванням представляють дати, datetime64[ns]хоча дати є лише щоденними. Цікаво, чи існує елегантний / розумний спосіб перетворення дат на datetime.dateабо datetime64[D]так, що коли я записую дані в CSV, дати не додаються 00:00:00. Я знаю, що я можу конвертувати тип вручну по елементам:

[dt.to_datetime().date() for dt in df.dates]

Але це дуже повільно, оскільки у мене багато рядків, і це якось перемагає мету використання pandas.to_datetime. Чи є спосіб перетворити dtypeвесь стовпець одночасно? Або, чи pandas.to_datetimeпідтримує специфікація точності, щоб я міг позбутися проміжок часу під час роботи з щоденними даними?

Відповіді:


295

Оскільки версію 0.15.0тепер це легко зробити за допомогою .dtдоступу лише до компонента дати:

df['just_date'] = df['dates'].dt.date

Наведене вище повертає datetime.datedtype, якщо ви хочете мати datetime64тоді, ви можете просто normalizeкомпонент часу до півночі, щоб він встановив усі значення 00:00:00:

df['normalised_date'] = df['dates'].dt.normalize()

Це зберігає dtype як, datetime64але на дисплеї відображається просто dateзначення.


37

Просте рішення:

df['date_only'] = df['date_time_column'].dt.date

Просто попередження, це змінює тип на об’єкт. Тож вам потрібно буде астипетизувати ('datetime64'), щоб зберегти послідовність.
misantroop

26

Хоча я підтримав відповідь EdChum, яка є найбільш прямою відповіддю на поставлене ОП питання, це насправді не вирішує проблему з продуктивністю (вона все ще покладається на datetimeоб'єкти python , а значить, будь-яка операція на них не буде векторизованою - тобто це буде повільно).

Більш ефективною альтернативою є використання df['dates'].dt.floor('d'). Строго кажучи, він не "зберігає лише частину дати", оскільки він просто встановлює час 00:00:00. Але це працює так, як хоче ОП, коли, наприклад:

  • друк на екран
  • економія в csv
  • за допомогою стовпця до groupby

... і це набагато ефективніше, оскільки операція векторизована.

EDIT: насправді, відповідь на ОП - х воліли б, ймовірно , «останні версії pandasцього НЕ пишуть час в форматі CSV , якщо це 00:00:00для всіх спостережень».


На жаль, to_jsonдосі пише повністю 00:00:00.
IanS

@IanS ти маєш на увазі під час використання date_format='iso'?! За замовчуванням він виводить лише секунди з епохи.
П'єтро Баттістон

Так, це я мав на увазі.
IanS

Це швидше, ніж dt.normalize()на серіях довше декількох сотень елементів.
C8H10N4O2

17

Панди DatetimeIndexі Seriesє метод , званий , normalizeщо робить саме те , що ви хочете.

Детальніше про це ви можете прочитати у цій відповіді .

Його можна використовувати як ser.dt.normalize()


17

Pandas v0.13 +: використовувати to_csvз date_formatпараметром

Уникайте, де це можливо, перетворення вашої datetime64[ns]серії в objectтиповий ряд datetime.dateоб'єктів. Останній, часто побудований за допомогою pd.Series.dt.date, зберігається як масив покажчиків і є неефективним щодо чистого ряду на основі NumPy.

Оскільки ваше занепокоєння є форматом під час запису в CSV , просто використовуйте date_formatпараметр to_csv. Наприклад:

df.to_csv(filename, date_format='%Y-%m-%d')

Див . strftimeДирективи Python щодо форматування конвенцій.


8

Це простий спосіб вилучити дату:

import pandas as pd

d='2015-01-08 22:44:09' 
date=pd.to_datetime(d).date()
print(date)

ОП вже використовує метод .date () у своєму запитанні, тому це рішення не відповідає на їх запитання, але я вважаю корисним побачити простий приклад використання методу date () як еталон.
Нік Скоцзаро

5

Перехід до datetime64[D]:

df.dates.values.astype('M8[D]')

Якщо повторне призначення цього коду DataFrame поверне його до [ns].

Якщо ви хотіли фактично datetime.date:

dt = pd.DatetimeIndex(df.dates)
dates = np.array([datetime.date(*date_tuple) for date_tuple in zip(dt.year, dt.month, dt.day)])

3
Якщо ви використовуєте astype ('M8 [D]'), він перетворює відсутні значення в дату початку, 1970-1-1. Напевно, краще просто просто зараз використовувати pandas.to_datetime ().
Стюбака

1
Зауважте усім, хто регулярно включає модуль дати, оскільки dtцей фрагмент відповіді замінить цей модуль! @ Dale-Jung, можливо, міг би змінити лінію на щось на кшталт dt_index
yeliabsalohcin

Я також знаходжу проблему, при якій наступного разу, коли я спробую додати новий рядок df.loc[date]методом, індекс повертається до часової позначки, тобто наступні порівняння більше не працюють
yeliabsalohcin

3

Просто дайте більш актуальну відповідь, якщо хтось побачить цю стару публікацію.

Додавання "utc = False" під час переходу в datetime видалить компонент часового поясу і збереже лише дату в типі даних datetime64 [ns].

pd.to_datetime(df['Date'], utc=False)

Ви зможете зберегти його в excel, не отримавши помилку "ValueError: Excel не підтримує дату з часовими поясами. Будь ласка, переконайтеся, що дати не знають часових поясів перед тим, як писати в Excel."

введіть тут опис зображення


Це чомусь не вдається після застосування будь-якої функції сукупності зі стовпцем.
RaphX

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.