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


105

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

例如 '2013-10-28'

目前该dtype列的是object

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

Answers:


110

使用类型

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
尼斯-谢谢-如何在每个日期结束时摆脱00:00:00?
user7289

1
熊猫时间戳记具有日期和时间。您的意思是将其转换为python date对象吗?
Waitingkuo 2013年

7
您可以将其转换为df['time'] = [time.date() for time in df['time']]
Waiting Kuo

3
[ns]是什么意思,您可以将文本字符串设为日期并删除该日期的时间部分吗?
yoshiserry

1
@yoshiserry是十亿分之一秒,这是将日期正确转换后(以毫秒为单位的时间)存储在内部的日期的方式。
安迪·海登

114

基本上等同于@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小号
如果碰上的情况下做

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

嗨,大家好,@ AndyHayden您可以从日期中删除时间部分吗?我不需要那一部分吗?
yoshiserry14年

在熊猫的0.13.1中,不显示尾随的00:00:00。
安迪·海登

以及在其他版本中,我们如何删除/和/或不显示它们?
yoshiserry

我不认为这可以用一种很好的方式完成,有讨论添加像float_format这样的date_format(您已经看到了)。我还是建议升级。
安迪·海登

我的问题是我的日期采用这种格式... 41516.43,出现此错误。我希望它在新列中返回类似于2014-02-03的内容吗?错误:#将“ load_date”列中的日期值转换为date budget_dataset ['date_last_load'] = pd.to_datetime(budget_dataset ['load_date'])budget_dataset -c:2:SettingWithCopyWarning:正在尝试在DataFrame中切片的副本。尝试改用.loc [row_index,col_indexer] = value
yoshiserry 2014年

36

我想象大量数据从CSV文件输入到Pandas中,在这种情况下,您可以简单地在初始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


谢谢,这正是我所需要的。该文档已移至,不过,你可以在这里找到:pandas.pydata.org/pandas-docs/stable/reference/api/...
Sastibe

24

现在你可以做 df['column'].dt.date

请注意,对于日期时间对象,如果您没有看到它们均为00:00:00的小时数,则说明它不是熊猫。那是iPython笔记本,试图使事情看起来更漂亮。


2
这对我不起作用,它抱怨:只能使用具有datetimelike值的.dt访问器
smishra,

2
您可能需要df[col] = pd.to_datetime(df[col])首先将列转换为日期时间对象。
szeitlin

这个答案的问题是,它将列转换成dtype = objectdatetime dtype在pandas中的true占用更多内存的列。
elPastor

6

执行此操作的另一种方法,如果您有多个要转换为日期时间的列,则此方法效果很好。

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

问题要求日期而不是日期时间。
Mark Andersen

@MarkAndersen,只要date列中只有值,转换为日期时间将仅保留相关信息。如果您明确地使用df['datetime_col'].dt.date进行转换,则会导致objectdtype;内存管理丢失。
Sumanth Lazarus


1

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

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

0

尝试使用pd.to_datetime函数将行之一转换为时间戳,然后使用.map将公式映射到整个列


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

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

import datetime
df["Date"] = df["Date"].apply(lambda x: datetime.datetime.strptime(x, '%Y-%d-%m').date())
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.