如何将熊猫数据框中的字符串转换为“日期”数据类型?

我有一个熊猫数据帧,其中一列包含格式为 YYYY-MM-DD的日期字符串

例如 '2013-10-28'

目前列的 dtypeobject

如何将列值转换为熊猫日期格式?

322305 次浏览

使用 类型

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

本质上等同于@wait ingkuo,但我在这里会使用 pd.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
如果你遇到这样的情况

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

抛出一个

ValueError: Unknown string format

这意味着您的值是无效的(非强制性的)。如果可以将它们转换为 pd.NaT,那么可以向 to_datetime添加一个 errors='coerce'参数:

df['time'] = pd.to_datetime(df['time'], errors='coerce')

我想大量的数据来自 CSV 文件,在这种情况下,你可以简单地转换日期在最初的 CSV 阅读:

其中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 笔记本,想让东西看起来更漂亮。

在这种情况下,可能需要将日期转换为不同的频率。在这种情况下,我建议按日期设置索引。

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

另一种方法是,如果有多个列要转换为 datetime,那么这种方法可以很好地工作。

cols = ['date1','date2']
df[cols] = df[cols].apply(pd.to_datetime)

如果希望获取 DATE 而不是 DATETIME 格式:

df["id_date"] = pd.to_datetime(df["id_date"]).dt.date

尝试使用 pd.to _ datetime 函数将其中一行转换为时间戳,然后使用。将公式映射到整个列

 #   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]

为了完整起见,另一个可能不是最直接的选项,有点类似于@SSS 提出的选项,但是使用 datetime 库是:

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