【问题标题】:How to convert string to datetime with nulls - python, pandas?如何使用空值将字符串转换为日期时间 - python,pandas?
【发布时间】:2015-05-31 15:45:51
【问题描述】:

我有一个包含一些日期时间(作为字符串)和一些空值作为“nan”的系列:

import pandas as pd, numpy as np, datetime as dt
df = pd.DataFrame({'Date':['2014-10-20 10:44:31', '2014-10-23 09:33:46', 'nan', '2014-10-01 09:38:45']})

我正在尝试将这些转换为日期时间:

df['Date'] = df['Date'].apply(lambda x: dt.datetime.strptime(x, '%Y-%m-%d %H:%M:%S'))

但我得到了错误:

time data 'nan' does not match format '%Y-%m-%d %H:%M:%S'

所以我试着把这些变成实际的空值:

df.ix[df['Date'] == 'nan', 'Date'] = np.NaN

然后重复:

df['Date'] = df['Date'].apply(lambda x: dt.datetime.strptime(x, '%Y-%m-%d %H:%M:%S'))

然后我得到错误:

必须是字符串,不能是浮点数

解决这个问题的最快方法是什么?

【问题讨论】:

    标签: python string datetime pandas type-conversion


    【解决方案1】:

    只需使用to_datetime 并设置errors='coerce' 来处理duff 数据:

    In [321]:
    
    df['Date'] = pd.to_datetime(df['Date'], errors='coerce')
    df
    Out[321]:
                     Date
    0 2014-10-20 10:44:31
    1 2014-10-23 09:33:46
    2                 NaT
    3 2014-10-01 09:38:45
    
    In [322]:
    
    df.info()
    <class 'pandas.core.frame.DataFrame'>
    Int64Index: 4 entries, 0 to 3
    Data columns (total 1 columns):
    Date    3 non-null datetime64[ns]
    dtypes: datetime64[ns](1)
    memory usage: 64.0 bytes
    

    调用strptime 的问题是如果字符串或dtype 不正确会引发错误。

    如果你这样做了,那么它会起作用:

    In [324]:
    
    def func(x):
        try:
            return dt.datetime.strptime(x, '%Y-%m-%d %H:%M:%S')
        except:
            return pd.NaT
    
    df['Date'].apply(func)
    Out[324]:
    0   2014-10-20 10:44:31
    1   2014-10-23 09:33:46
    2                   NaT
    3   2014-10-01 09:38:45
    Name: Date, dtype: datetime64[ns]
    

    但使用内置的to_datetime 会更快,而不是调用apply,后者基本上只是循环您的系列。

    时间

    In [326]:
    
    %timeit pd.to_datetime(df['Date'], errors='coerce')
    %timeit df['Date'].apply(func)
    10000 loops, best of 3: 65.8 µs per loop
    10000 loops, best of 3: 186 µs per loop
    

    我们在这里看到使用to_datetime 的速度提高了 3 倍。

    【讨论】:

    • 当前语法现在是errors='coerce',而不是coerce=True
    【解决方案2】:

    我发现让 pandas 在大型数据帧上完成这项工作太慢了。在另一篇文章中,我学到了一种技术,当唯一值的数量远小于行数时,这种技术可以显着加快速度。 (我的数据通常是股票价格或交易记录数据。)它首先构建一个字典,将文本日期映射到它们的日期时间对象,然后应用该字典来转换文本日期列。

    def str2time(val):
        try:
            return dt.datetime.strptime(val, '%H:%M:%S.%f')
        except:
            return pd.NaT
    
    def TextTime2Time(s):
        times = {t : str2time(t) for t in s.unique()}
        return s.apply(lambda v: times[v])
    
    df.date = TextTime2Time(df.date)
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-24
      • 2019-03-14
      • 1970-01-01
      • 2015-11-19
      相关资源
      最近更新 更多