У меня есть фрейм данных Pandas, один из столбцов содержит строки даты в формате YYYY-MM-DD
Например, '2013-10-28'
На данный момент dtype
столбец есть object
.
Как преобразовать значения столбцов в формат даты Pandas?
Ответы:
Используйте 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']]
По сути эквивалент @waitingkuo, но я бы использовал to_datetime
здесь (он кажется немного чище и предлагает некоторые дополнительные функции, например 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
Обработка ValueError
s
Если вы столкнетесь с ситуацией, когда
df['time'] = pd.to_datetime(df['time'])
Бросает
ValueError: Unknown string format
Это означает, что у вас есть недопустимые (непринудительные) значения. Если вы согласны с их преобразованием в pd.NaT
, вы можете добавить errors='coerce'
аргумент в to_datetime
:
df['time'] = pd.to_datetime(df['time'], errors='coerce')
Я предполагаю, что много данных поступает в Pandas из файлов CSV, и в этом случае вы можете просто преобразовать дату во время первоначального чтения CSV:
dfcsv = pd.read_csv('xyz.csv', parse_dates=[0])
где 0 относится к столбцу, в котором находится дата.
Вы также можете добавить , index_col=0
туда, если хотите, чтобы дата была вашим индексом.
См. Https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html
Теперь ты можешь сделать df['column'].dt.date
Обратите внимание, что для объектов datetime, если вы не видите час, когда они все 00:00:00, это не панды. Ноутбук iPython пытается сделать вещи красивыми.
df[col] = pd.to_datetime(df[col])
сначала преобразовать столбец в объекты даты и времени.
dtype = object
который занимает значительно больше памяти, чем истинный datetime dtype
в pandas.
Другой способ сделать это, и он хорошо работает, если у вас есть несколько столбцов для преобразования в datetime.
cols = ['date1','date2']
df[cols] = df[cols].apply(pd.to_datetime)
date
только значения в столбцах, преобразование в datetime сохранит только относящуюся к делу информацию. Если вы явно конвертируете с помощью df['datetime_col'].dt.date
, это приведет к object
dtype; потеря в управлении памятью.
Если вы хотите получить формат DATE, а не DATETIME:
df["id_date"] = pd.to_datetime(df["id_date"]).dt.date
Может случиться так, что даты необходимо преобразовать с другой частотой. В этом случае я бы предложил установить индекс по датам.
#set an index by dates
df.set_index(['time'], drop=True, inplace=True)
После этого вы сможете более легко преобразовать дату в формат даты, который вам больше всего понадобится. Ниже я последовательно конвертирую в несколько форматов даты, в конечном итоге получая набор ежедневных дат в начале месяца.
#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)
Для краткости я не показываю, что запускаю следующий код после каждой строки выше:
print(df.index)
print(df.index.dtype)
print(type(df.index))
Это дает мне следующий результат:
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'>
Попробуйте преобразовать одну из строк в метку времени с помощью функции pd.to_datetime, а затем используйте .map для сопоставления формуляра со всем столбцом
# 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]