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

cms*_*mgr 21 python datetime pandas

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

12/01/2012
30/01/2012
Run Code Online (Sandbox Code Playgroud)

上述示例代表2012年1月12日和2012年1月30日.

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

import pandas as pd
...
cpts.Date = cpts.Date.apply(pd.to_datetime)
Run Code Online (Sandbox Code Playgroud)

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

看了这个问题之后我试了一下:

cpts.Date = cpts.Date.apply(pd.to_datetime, format='%d/%m/%Y')
Run Code Online (Sandbox Code Playgroud)

但结果完全一样.该源代码表明我正在做正确的事情,所以我无所适从.有谁知道我做错了什么?

jor*_*ris 22

您可以使用parse_dates选项read_csv从而在读取数据时直接进行转换.
这里的诀窍是用来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
Run Code Online (Sandbox Code Playgroud)

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

>>> 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
Run Code Online (Sandbox Code Playgroud)

  • 请注意:[dayfirst不严格](https://github.com/pydata/pandas/issues/3341). (3认同)
  • 您还可以设置自定义解析器,这对我来说没问题:`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认同)

And*_*den 10

我认为你正确地调用它,我在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]
Run Code Online (Sandbox Code Playgroud)

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

s.apply(pd.to_datetime, dayfirst=True)
Run Code Online (Sandbox Code Playgroud)

值得注意的是必须小心使用dayfirst(这比指定确切的格式更容易),因为dayfirst并不严格.

  • 如果只有某人标准化了国际日期格式.哦,[等等](http://xkcd.com/1179/). (3认同)