我有一个数据集,其中小时记录为[0100:2400]
,而不是[0000:2300]
例如
pd.to_datetime('201704102300', format='%Y%m%d%H%M')
返回
Timestamp('2017-04-10 20:00:00')
但是
pd.to_datetime('201704102400', format='%Y%m%d%H%M')
给我错误:
ValueError:未转换的数据仍为:0
如何解决此问题?
我可以手动调整数据,例如本SO Post中提到的数据,但我认为大熊猫应该已经处理了这个案例?
更新:
答案 0 :(得分:5)
Pandas使用系统strptime
,所以如果你需要非标准的东西,你可以自己动手。
<强>代码:强>
import pandas as pd
import datetime as dt
def my_to_datetime(date_str):
if date_str[8:10] != '24':
return pd.to_datetime(date_str, format='%Y%m%d%H%M')
date_str = date_str[0:8] + '00' + date_str[10:]
return pd.to_datetime(date_str, format='%Y%m%d%H%M') + \
dt.timedelta(days=1)
print(my_to_datetime('201704102400'))
<强>结果:强>
2017-04-11 00:00:00
对于pandas.DataFrame
中的列:
df['time'] = df.time.apply(my_to_datetime)
答案 1 :(得分:4)
矢量化解决方案,使用pd.to_datetime(DataFrame)方法:
来源DF
In [27]: df
Out[27]:
time
0 201704102400
1 201602282400
2 201704102359
<强>解决方案强>
In [28]: pat = '(?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2})(?P<hour>\d{2})(?P<minute>\d{2})'
In [29]: pd.to_datetime(df['time'].str.extract(pat, expand=True))
Out[29]:
0 2017-04-11 00:00:00
1 2016-02-29 00:00:00
2 2017-04-10 23:59:00
dtype: datetime64[ns]
说明:
In [30]: df['time'].str.extract(pat, expand=True)
Out[30]:
year month day hour minute
0 2017 04 10 24 00
1 2016 02 28 24 00
2 2017 04 10 23 59
pat
是Series.str.extract()函数
更新:时间
In [37]: df = pd.concat([df] * 10**4, ignore_index=True)
In [38]: df.shape
Out[38]: (30000, 1)
In [39]: %timeit df.time.apply(my_to_datetime)
1 loop, best of 3: 4.1 s per loop
In [40]: %timeit pd.to_datetime(df['time'].str.extract(pat, expand=True))
1 loop, best of 3: 475 ms per loop
答案 2 :(得分:0)
基于@MaxU 的回答,通过对输入字符串进行切片、将日期直接解析为 datetime 并将其余部分添加为 timedelta,可以获得更高的效率。例如:
df = pd.DataFrame({'time': ["201704102400", "201602282400","201704102359"]})
df['time'] = (pd.to_datetime(df['time'].str[:8], format='%Y%m%d') +
pd.to_timedelta(df['time'].str[8:10]+':'+df['time'].str[10:12]+':00'))
df['time']
0 2017-04-11 00:00:00
1 2016-02-29 00:00:00
2 2017-04-10 23:59:00
Name: time, dtype: datetime64[ns]
30k 个元素的相对 %timeit
比较 df 显示出舒适的 x2 改进:
%timeit pd.to_datetime(df['time'].str[:8], format='%Y%m%d') + pd.to_timedelta(df['time'].str[8:10]+':'+df['time'].str[10:12]+':00')
50 ms ± 270 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit pd.to_datetime(df['time'].str.extract(pat, expand=True))
122 ms ± 1.3 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)
%timeit df.time.apply(my_to_datetime)
3.34 s ± 3.26 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)