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?

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

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

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


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ć.


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)

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


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

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ę


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]

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())
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.