Jak przekonwertować daty w ramce danych Pandas na typ danych „data”?

105

Mam ramkę danych Pandas, jedna z kolumn zawiera ciągi daty w formacie YYYY-MM-DD

Np '2013-10-28'

W tej chwili dtypekolumna jest object.

Jak przekonwertować wartości kolumn na format daty Pandas?

user7289
źródło

Odpowiedzi:

110

Użyj astype

In [31]: df
Out[31]: 
   a        time
0  1  2013-01-01
1  2  2013-01-02
2  3  2013-01-03

In [32]: df['time'] = df['time'].astype('datetime64[ns]')

In [33]: df
Out[33]: 
   a                time
0  1 2013-01-01 00:00:00
1  2 2013-01-02 00:00:00
2  3 2013-01-03 00:00:00
waitkuo
źródło
1
Świetnie - dziękuję - jak pozbyć się godziny 00:00:00 pod koniec każdej randki?
user7289
1
Znacznik czasu pandy zawiera zarówno datę, jak i godzinę. Czy masz na myśli przekonwertowanie go na obiekt daty w Pythonie?
waitkuo
7
Możesz go przeliczyć dodf['time'] = [time.date() for time in df['time']]
waitkuo
3
co oznacza [ns], czy możesz ustawić w ciągu tekstowym datę i usunąć część czasu z tej daty?
yoshiserry
1
@yoshiserry to nanosekundy i jest to sposób, w jaki daty są przechowywane pod maską po prawidłowej konwersji (czas epoki w nanosekundach).
Andy Hayden,
114

Zasadniczo odpowiednik @waitingkuo, ale użyłbym to_datetimetutaj (wydaje się trochę czystszy i oferuje dodatkowe funkcje, np. dayfirst):

In [11]: df
Out[11]:
   a        time
0  1  2013-01-01
1  2  2013-01-02
2  3  2013-01-03

In [12]: pd.to_datetime(df['time'])
Out[12]:
0   2013-01-01 00:00:00
1   2013-01-02 00:00:00
2   2013-01-03 00:00:00
Name: time, dtype: datetime64[ns]

In [13]: df['time'] = pd.to_datetime(df['time'])

In [14]: df
Out[14]:
   a                time
0  1 2013-01-01 00:00:00
1  2 2013-01-02 00:00:00
2  3 2013-01-03 00:00:00

Obsługa ValueErrors
Jeśli napotkasz sytuację, w której robisz

df['time'] = pd.to_datetime(df['time'])

Rzuca

ValueError: Unknown string format

Oznacza to, że masz nieprawidłowe (niewymuszalne) wartości. Jeśli nie przeszkadza Ci przekonwertowanie ich na pd.NaT, możesz dodać errors='coerce'argument do to_datetime:

df['time'] = pd.to_datetime(df['time'], errors='coerce')
Andy Hayden
źródło
Cześć chłopaki, @AndyHayden, czy możecie usunąć część czasu z daty? Nie potrzebuję tej części?
yoshiserry
W pandach 0.13.1 końcowe 00: 00: 00 nie są wyświetlane.
Andy Hayden,
a co z innymi wersjami, w jaki sposób je usuwamy / lub nie wyświetlamy?
yoshiserry,
Nie sądzę, aby można to było zrobić w przyjemny sposób, istnieje dyskusja na temat dodawania formatu date_format, takiego jak float_format (który widziałeś). Mimo wszystko zalecam aktualizację.
Andy Hayden,
mój problem polega na tym, że moja data jest w tym formacie ... 41516.43 i otrzymuję ten błąd. Spodziewałbym się, że w nowej kolumnie zwróci coś jak 2014-02-03 ?! BŁĄD: # konwertuj wartości dat w kolumnie „load_date” na daty budget_dataset ['date_last_load'] = pd.to_datetime (budget_dataset ['load_date']) budget_dataset -c: 2: SettingWithCopyWarning: Próba ustawienia wartości na kopia wycinka z DataFrame. Spróbuj użyć zamiast tego .loc [row_index, col_indexer] = value
yoshiserry
36

Wyobrażam sobie, że wiele danych trafia do Pand z plików CSV, w takim przypadku możesz po prostu przekonwertować datę podczas początkowego odczytu CSV:

dfcsv = pd.read_csv('xyz.csv', parse_dates=[0])gdzie 0 odnosi się do kolumny, w której znajduje się data.
Możesz również dodać , index_col=0tam datę, jeśli chcesz, aby data była indeksem.

Zobacz https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html

fantabolous
źródło
Dzięki, właśnie tego potrzebowałem. Dokumentacja została przeniesiona, ale możesz ją znaleźć tutaj: pandas.pydata.org/pandas-docs/stable/reference/api/…
Sastibe
24

Teraz możesz to zrobić df['column'].dt.date

Zauważ, że w przypadku obiektów datetime, jeśli nie widzisz godziny, w której wszystkie są 00:00:00, to nie są pandy. To notebook iPython, który próbuje ładnie wyglądać.

szeitlin
źródło
2
Ten nie działa dla mnie, narzeka: można używać tylko akcesorium .dt z wartościami
podobnymi do dat
2
być może będziesz musiał zrobić df[col] = pd.to_datetime(df[col])najpierw, aby przekonwertować kolumnę na obiekty daty i godziny.
szeitlin
Problem z tą odpowiedzią polega na tym, że konwertuje ona kolumnę, dtype = objectktóra zajmuje znacznie więcej pamięci niż prawda datetime dtypeu pand.
elPastor
6

Inny sposób na zrobienie tego i działa dobrze, jeśli masz wiele kolumn do konwersji na datę i godzinę.

cols = ['date1','date2']
df[cols] = df[cols].apply(pd.to_datetime)
SSS
źródło
Pytanie pytaj o datę, a nie datę i godzinę.
Mark Andersen,
@MarkAndersen tak długo, jak masz datetylko wartości w swoich kolumnach, konwersja na datetime zachowa tylko odpowiednie informacje. Jeśli dokonasz bezpośredniej konwersji za pomocą df['datetime_col'].dt.datetego, da to objectdtype; utrata zarządzania pamięcią.
Sumanth Lazarus
5

Jeśli chcesz uzyskać format DATA, a nie DATETIME:

df["id_date"] = pd.to_datetime(df["id_date"]).dt.date
David Valenzuela Urrutia
źródło
1

Może się zdarzyć, że daty będą musiały zostać zamienione na inną częstotliwość. W takim przypadku sugerowałbym ustawienie indeksu według dat.

#set an index by dates
df.set_index(['time'], drop=True, inplace=True)

Następnie możesz łatwiej przekonwertować na typ formatu daty, którego będziesz najbardziej potrzebować. Poniżej sekwencyjnie konwertuję na kilka formatów dat, ostatecznie kończąc na zestawie dat dziennych na początku miesiąca.

#Convert to daily dates
df.index = pd.DatetimeIndex(data=df.index)

#Convert to monthly dates
df.index = df.index.to_period(freq='M')

#Convert to strings
df.index = df.index.strftime('%Y-%m')

#Convert to daily dates
df.index = pd.DatetimeIndex(data=df.index)

Dla zwięzłości nie pokazuję, że po każdym powyższym wierszu uruchamiam następujący kod:

print(df.index)
print(df.index.dtype)
print(type(df.index))

To daje mi następujący wynik:

Index(['2013-01-01', '2013-01-02', '2013-01-03'], dtype='object', name='time')
object
<class 'pandas.core.indexes.base.Index'>

DatetimeIndex(['2013-01-01', '2013-01-02', '2013-01-03'], dtype='datetime64[ns]', name='time', freq=None)
datetime64[ns]
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>

PeriodIndex(['2013-01', '2013-01', '2013-01'], dtype='period[M]', name='time', freq='M')
period[M]
<class 'pandas.core.indexes.period.PeriodIndex'>

Index(['2013-01', '2013-01', '2013-01'], dtype='object')
object
<class 'pandas.core.indexes.base.Index'>

DatetimeIndex(['2013-01-01', '2013-01-01', '2013-01-01'], dtype='datetime64[ns]', freq=None)
datetime64[ns]
<class 'pandas.core.indexes.datetimes.DatetimeIndex'>
Ted M.
źródło
0

Spróbuj przekonwertować jeden z wierszy na znacznik czasu za pomocą funkcji pd.to_datetime, a następnie użyj .map, aby zmapować formular na całą kolumnę

Mwanaidi Nicole
źródło
0
 #   Column          Non-Null Count   Dtype         
---  ------          --------------   -----         
 0   startDay        110526 non-null  object
 1   endDay          110526 non-null  object

import pandas as pd

df['startDay'] = pd.to_datetime(df.startDay)

df['endDay'] = pd.to_datetime(df.endDay)

 #   Column          Non-Null Count   Dtype         
---  ------          --------------   -----         
 0   startDay        110526 non-null  datetime64[ns]
 1   endDay          110526 non-null  datetime64[ns]
donDrey
źródło
0

Ze względu na kompletność inną opcją, która może nie być najprostsza, trochę podobną do tej proponowanej przez @SSS, ale używającą raczej biblioteki datetime jest:

import datetime
df["Date"] = df["Date"].apply(lambda x: datetime.datetime.strptime(x, '%Y-%d-%m').date())
rubebop
źródło