将str系列转换为日期

时间:2018-11-23 18:39:00

标签: python pandas datetime

我正在进行一场噩梦,将一系列字符串转换为日期。这是我的数据示例:

net_due_date                from_date   clearing_date
0   2018-10-25 00:00:00.000 2017-06-06  2018-10-13 00:00:00.000
1   2018-09-27 00:00:00.000 2017-06-06  2018-09-30 00:00:00.000
2   2018-05-31 00:00:00.000 2017-06-06  2018-05-18 00:00:00.000
3   2017-12-22 00:00:00.000 2017-06-06  2017-12-08 00:00:00.000
4   2018-01-30 00:00:00.000 2017-06-06  2018-01-16 00:00:00.000
5   2018-07-31 00:00:00.000 2017-06-06  2018-07-31 00:00:00.000
6   2018-05-29 00:00:00.000 2017-06-06  2018-05-17 00:00:00.000
7   2017-12-14 00:00:00.000 2017-06-06  2017-12-08 00:00:00.000
8   2017-11-24 00:00:00.000 2017-06-06  2017-12-08 00:00:00.000
9   2018-09-27 00:00:00.000 2017-06-06  2018-09-13 00:00:00.000
10  2018-01-25 00:00:00.000 2017-06-06  2018-01-16 00:00:00.000
11  2017-11-24 00:00:00.000 2017-06-06  2017-11-30 00:00:00.000
12  2018-10-24 00:00:00.000 2018-01-09  2018-10-11 00:00:00.000
13  2018-01-22 00:00:00.000 2018-01-09  2018-10-10 00:00:00.000
14  2018-09-06 00:00:00.000 2018-01-09  2018-10-10 00:00:00.000
15  2018-10-24 00:00:00.000 2018-01-09  2018-10-10 00:00:00.000
16  2018-06-15 00:00:00.000 2018-01-09  2018-10-10 00:00:00.000
17  2018-04-10 00:00:00.000 2018-01-09  2018-10-10 00:00:00.000
18  2018-01-12 00:00:00.000 2018-01-09  2018-10-10 00:00:00.000
19  2018-01-24 00:00:00.000 2018-01-09  2018-10-10 00:00:00.000

这些是dtypes

net_due_date     object
from_date        object
clearing_date    object
dtype: object

我正在尝试将所有这些数据转换为相同的格式,以便可以在其上运行函数以计算日期之间的差异。

以下代码在net_due_date上运行良好:

df['net_due_date'] = pd.to_datetime(df['net_due_date'], format='%Y-%m-%d')

类似的代码也可以在from_date上正常工作

df['from_date'] = pd.to_datetime(df['from_date'], format='%Y-%m-%d')

但是,clearing_date中有一些值为9999-12-31的值,当我运行相同的代码时,出现以下错误:

OutOfBoundsDatetime: Out of bounds nanosecond timestamp: 9999-12-31 00:00:00

我实际上花了几个小时来解决这个问题,我最接近的就是这个链接: Time Series, OOB Timestamps

但是随后我遇到了以下错误:

TypeError: unsupported operand type(s) for //: 'str' and 'int'

要解决此问题,我尝试先使用to_numeric将列转换为int,但又遇到了其他一系列错误。我希望有人以前曾经遇到过这个问题,可以提供帮助,因为我无法在线找到任何东西来解决此问题!

2 个答案:

答案 0 :(得分:1)

您可以使用相同方法的errors argument

  

错误 {“忽略”,“提高”,“胁迫”},默认的“提高”

     
      
  • 如果为“ raise”,则无效的解析将引发异常

  •   
  • 如果为“强制”,则无效解析将设置为NaT

  •   
  • 如果为“ ignore”,则无效的解析将返回输入

  •   

这一行应该为您解决问题:

df = df.apply(lambda x: pd.to_datetime(x, errors='coerce'))

# results:
#    net_due_date  from_date  clearing_date
# ...
# 10   2018-01-25 2017-06-06     2018-01-16
# 11   2017-11-24 2017-06-06            NaT
# 12   2018-10-24 2018-01-09     2018-10-11
# ...

如有必要,您可以随后为DataFrame按摩NaT并转换为对您有意义的内容,例如:

df.fillna(pd.datetime.now().date(), inplace=True)

#    net_due_date  from_date  clearing_date    
# 10   2018-01-25 2017-06-06     2018-01-16
# 11   2017-11-24 2017-06-06     2018-11-23 # <-- changed to today
# 12   2018-10-24 2018-01-09     2018-10-11

只是为了确认dtypes

net_due_date      datetime64[ns]
 from_date        datetime64[ns]
 clearing_date    datetime64[ns]
dtype: object

答案 1 :(得分:1)

我假设您的情况下所有列均为String类型,并且包含日期 +有时是一部分。所以最简单的选择是:

df = df.applymap(pd.to_datetime)

运行以下脚本来转换部分源数据:

import pandas as pd

dd = { 'net_due_date': [ '2018-10-25 00:00:00.000', '2018-09-27 00:00:00.000',
        '2018-05-31 00:00:00.000', '2017-12-22 00:00:00.000',
        '2018-01-30 00:00:00.000' ],
    'from_date': [ '2017-06-06', '2017-06-06', '2017-06-06', '2017-06-06', '2017-06-06' ],
    'clearing_date': [ '2018-10-13 00:00:00.000', '2018-09-30 00:00:00.000',
        '2018-05-18 00:00:00.000', '2017-12-08 00:00:00.000', '2018-01-16 00:00:00.000' ] }
df = pd.DataFrame(data=dd)
df = df.applymap(pd.to_datetime)

执行df.info()时,您将获得(打印输出的一部分):

Data columns (total 3 columns):
net_due_date     5 non-null datetime64[ns]
from_date        5 non-null datetime64[ns]
clearing_date    5 non-null datetime64[ns]

出于演示目的,您可以在前后添加print(df) 转换。

就“非常大”的年份而言,熊猫将日期转换为 年份介于1677和2262之间。因此,也许第一步 您应将超出范围的日期更改为例如2250。