Mam ramkę danych Pandas, jedna z kolumn zawiera ciągi daty w formacie YYYY-MM-DD
Np '2013-10-28'
W tej chwili dtype
kolumna jest object
.
Jak przekonwertować wartości kolumn na format daty Pandas?
Odpowiedzi:
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
df['time'] = [time.date() for time in df['time']]
Zasadniczo odpowiednik @waitingkuo, ale użyłbym to_datetime
tutaj (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 ValueError
s
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')
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=0
tam datę, jeśli chcesz, aby data była indeksem.
Zobacz https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html
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ć.
df[col] = pd.to_datetime(df[col])
najpierw, aby przekonwertować kolumnę na obiekty daty i godziny.
dtype = object
która zajmuje znacznie więcej pamięci niż prawda datetime dtype
u pand.
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)
date
tylko wartości w swoich kolumnach, konwersja na datetime zachowa tylko odpowiednie informacje. Jeśli dokonasz bezpośredniej konwersji za pomocą df['datetime_col'].dt.date
tego, da to object
dtype; utrata zarządzania pamięcią.
Jeśli chcesz uzyskać format DATA, a nie DATETIME:
df["id_date"] = pd.to_datetime(df["id_date"]).dt.date
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'>
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ę
# 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]