如何将包含空值的字符串转化为日期时间格式 - Python、Pandas?

33

我有一个包含一些日期时间(以字符串形式)和一些空值'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'

所以我尝试将它们转换为实际的null值:

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'))

但是我遇到了这个错误:

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

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

2个回答

62

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

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的问题在于,如果字符串或数据类型不正确,它会引发错误。

如果你这样做,那么它就能工作:

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倍。


11
当前的语法现在是errors='coerce',而不是coerce=True - JBWhitmore

4

我发现让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)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接