使用 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_datetime
的 coerce
参数可以解决这个问题,但在稳定版本之前我无法升级我的工作环境。
@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