使用 pandas.to_datetime 转换时指定日期格式

Posted

技术标签:

【中文标题】使用 pandas.to_datetime 转换时指定日期格式【英文标题】:Specifying date format when converting with pandas.to_datetime 【发布时间】:2013-05-16 08:26:57 【问题描述】:

我有一个 csv 文件中的数据,其中日期以标准英国格式存储为字符串 - %d/%m/%Y - 意味着它们看起来像:

12/01/2012
30/01/2012

以上示例代表 2012 年 1 月 12 日和 2012 年 1 月 30 日。

当我使用 pandas 0.11.0 版导入此数据时,我应用了以下转换:

import pandas as pd
...
cpts.Date = cpts.Date.apply(pd.to_datetime)

但它转换的日期不一致。使用我现有的示例,12/01/2012 将转换为代表 2012 年 12 月 1 日的日期时间对象,但 30/01/2012 转换为 2012 年 1 月 30 日,这正是我想要的。

看了this question我试了一下:

cpts.Date = cpts.Date.apply(pd.to_datetime, format='%d/%m/%Y')

但结果完全一样。 source code 表明我做对了,所以我很茫然。有谁知道我做错了什么?

【问题讨论】:

你用过read_csv吗?因为那样你就可以在阅读的时候直接做。 @joris 是的,我确实使用了read_csv。你能告诉我日期转换是什么函数吗?它处理我的格式问题吗? 但是回到你原来的问题(因为这也应该有效),你使用的是什么版本,因为对我来说它有效。 @joris 在 11.0 和 dev 中似乎是这种情况,发布为 issue on github 是的,访问单个列将返回一个系列。所以你可以尝试cpts[['Date']].apply(pd.to_datetime, ...) 作为一种解决方法(由于双 [ 它会返回一个包含一列的数据框)。但请注意,它也应该适用于系列(它不是一个错误),并且更简单的方法是直接在列上调用pd.to_datetime(..)@AndyHayden 在他的回答中指出或进行转换在read_csv. 【参考方案1】:

您可以使用read_csv 中的parse_dates 选项在读取数据时直接进行转换。 这里的诀窍是使用dayfirst=True 来指示您的日期从当天开始,而不是从月份开始。更多信息请看这里:http://pandas.pydata.org/pandas-docs/dev/generated/pandas.io.parsers.read_csv.html

当你的日期必须是索引时:

>>> import pandas as pd
>>> from StringIO import StringIO
>>> s = StringIO("""date,value
... 12/01/2012,1
... 12/01/2012,2
... 30/01/2012,3""")
>>> 
>>> pd.read_csv(s, index_col=0, parse_dates=True, dayfirst=True)
            value
date             
2012-01-12      1
2012-01-12      2
2012-01-30      3

或者当您的日期只是在某个列中时:

>>> s = StringIO("""date
... 12/01/2012
... 12/01/2012
... 30/01/2012""")
>>> 
>>> pd.read_csv(s, parse_dates=[0], dayfirst=True)
                 date
0 2012-01-12 00:00:00
1 2012-01-12 00:00:00
2 2012-01-30 00:00:00

【讨论】:

你也可以设置一个自定义解析器,这对我来说没问题:df = pd.read_csv("file.csv", parse_dates=['date_column'], date_parser=lambda d: pd.to_datetime(d, format="%Y/%m/%d", errors="coerce"))【参考方案2】:

我认为您的称呼是正确的,我将其发布为 an issue on github。

您可以直接指定格式为to_datetime,例如:

In [1]: s = pd.Series(['12/1/2012', '30/01/2012'])

In [2]: pd.to_datetime(s, format='%d/%m/%Y')
Out[2]:
0   2012-01-12 00:00:00
1   2012-01-30 00:00:00
dtype: datetime64[ns]

更新:正如 OP 正确指出的那样,这不适用于 NaN,如果您对 dayfirst=True(也适用于 NaN)感到满意:

s.apply(pd.to_datetime, dayfirst=True)

值得注意的是,必须小心使用dayfirst(这比指定确切格式更容易),因为dayfirst isn't strict。

【讨论】:

感谢这个解决方案很有吸引力,但它目前不适用于我拥有的丢失数据。我怀疑 dev 中 pd.to_datetimecoerce 参数可以解决这个问题,但在稳定版本之前我无法升级我的工作环境。 @cms_mgr 怎么样:s.apply(lambda t: pd.to_datetime(t, format='%d/%m/%Y')),使用 NaN。 恐怕这仍然与日期有关。看起来这是一个错误 - 认为这可能是我发现的第一个! 如果有人标准化了国际日期格式就好了。哦,wait. @cms_mgr 实际上我记得之前测试过(但它不起作用)。我认为这可能是一个错误......

以上是关于使用 pandas.to_datetime 转换时指定日期格式的主要内容,如果未能解决你的问题,请参考以下文章

python 将列转换为pandas to_datetime()

使用具有正确语法的 pandas to_datetime() 方法,无法识别的值类型:str?

如何使用pandas将hhmmss.ff格式转换为datetime

Python Pandas:当日期小于 13 时,pandas.to_datetime() 正在切换日期和月份

使用 Pandas 将字符串格式化为日期时间 - 指令问题

007.pandas.to_datetime()