我有一个系列有一些日期时间(作为字符串)和一些空值为'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'))
然后我收到错误:
必须是字符串,而不是浮动
解决此问题的最快方法是什么?
答案 0 :(得分:22)
只需使用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倍。
答案 1 :(得分:0)
我发现让大熊猫在大型数据帧上的工作太慢了。在另一篇文章中,我了解了一种技术,当唯一值的数量远小于行数时,这种技术可以大大提高速度。 (我的数据通常是股票价格或交易记录数据。)它首先构建一个dict,将文本日期映射到它们的datetime对象,然后应用dict转换文本日期列。
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)