pandas to_datetime 处理混合时间格式数据实战与避坑指南
本文详解 pandas 中 to_datetime 函数的使用,重点解决 DataFrame 中混合时间格式导致的转换报错。通过实战案例,展示如何识别 object 类型日期列,利用 errors='coerce' 和 infer_datetime_format 参数处理包含 ISO8601 等不一致格式的数据,并提供筛选异常行与批量转换的高效技巧。
前言与背景
前言
在一次网络竞赛中,我遇到了一道由外国人编写的英文题目,尽管语言存在障碍,但其内容极具学习价值,值得深入钻研。在此,我将本次实践中的核心收获整理记录,既作为个人学习资料的存档,也分享给广大开发者参考交流。
(收获了对处理大数据的又一次认识!!!)
时间格式转换基础
该题目要求将 DataFrame 中的日期数据转换为 Python 可识别的标准格式,本文重点讲解 to_datetime 函数的具体应用与技巧。
首先明确时间字符串的格式规范:
- 1/17/07 对应格式 "%m/%d/%y"
- 17-1-2007 对应格式 "%d-%m-%Y"
掌握上述格式规则后,即可将 DataFrame 中的时间字符串转换为 Python 内部的 datetime 类型。
0 2007-03-02
1 2007-03-22
2 2007-04-06
3 2007-04-14
4 2007-04-15
Name: date_parsed, dtype: datetime64[ns]
观察转换结果,可以看到 dtype 显示为 datetime64,这表明转换成功。若直接查看原始数据列的 dtype,通常会发现其类型为 object。在 Python 中,object 类型通常用于存储可变对象,它无法被自动识别为时间格式,尽管人类肉眼可以直观判断。这正是人机处理数据的差异所在。
data = pd.read_csv('path') #这里我们得到data数据
data['date'].heade() #查看一下日期列的样子
0 01/02/1965
1 01/04/1965
2 01/05/1965
3 01/08/1965
4 01/09/1965
Name: Date, dtype: object
确认原始数据为 object 格式,而非日期格式。
data['date_parsed'] = pd.to_datetime(data['date'],format="%m/%d/%y")
上述代码展示了如何将转换后的时间数据添加至 DataFrame 的新列中。
dara['date_parsed'].head() #查看一下结果
0 1965-01-02
1 1965-01-04
2 1965-01-05
3 1965-01-08
4 1965-01-09
Name: data_parsed, dtype: datetime64[ns]
此时,数据的形式和类型均已改变。但这仅是基础操作,若仅止步于此,本文的价值便大打折扣。
混合格式转换报错分析
实际上,在使用上述语句进行时间转换时,往往会遇到意想不到的困难:
/opt/conda/lib/python3.6/site-packages/pandas/core/tools/datetimes.py in _convert_listlike(arg, box, format, name, tz)
271 try:
272 result = array_strptime(arg, format, exact=exact,
--> 273 errors=errors)
274 except tslib.OutOfBoundsDatetime:
275 if errors == 'raise':
pandas/_libs/tslibs/strptime.pyx in pandas._libs.tslibs.strptime.array_strptime()
ValueError: time data '1975-02-23T02:58:41.000Z' does not match format '%m/%d/%Y' (match)
部分错误信息如下所示。
面对加载缓慢的大数据量,转换过程中出现错误会让人感到无助。若逐一排查数据,可能需要耗费大量时间。
或许有人会说,错误信息已经提示了问题所在。确实如此,但当数据量庞大时,面对纷繁复杂的报错信息,初学者往往感到迷茫。我曾花费半天时间尝试其他转换方式却无果而终,最终静下心来分析报错信息,发现其中存在无法转换的特定格式。
'1975-02-23T02:58:41.000Z'
因此,我尝试调整格式以匹配时分秒,却又提示年月日不匹配。经过反复验证,推测原始数据存在格式不统一的问题。既然找到了根源,便可针对性地修改解决方案。
异常数据处理与解决方案
我的第一次修改方案如下:
data['over_long'] = data['Date'].apply(len) #添加一列记录没行时间的长度
data.loc[data['over_long'] > 10] #输出大于正常数据的行 这里会发现缺失有那么几行在作怪!!!
normal_dates = data.loc[data['over_long'] < 11] #筛选出正常数据
normal_dates = normal_dates.copy() #拷贝
normal_dates['data_parsed'] = pd.to_datetime(normal_dates['Date'],format='%m/%d/%Y') #再次转换时间,发现没有报错了 哈哈
normal_dates['data_parsed'].head(10) #输出查看没问题的
以上是我最初尝试的解决方法。
随后,在他人指导下,我了解了其他几种更优的处理方法(毕竟直接删除数据并非最佳实践)。
第一种和第二种方法如下:
data['date_parsed'] = pd.to_datetime(data['Date'], format = "%m/%d/%Y", errors = 'coerce')
data['date_parsed'] = pd.to_datetime(data['Date'],infer_datetime_format=True)
这两种方法均能实现预期效果,我进行了测试。由于对 to_datetime 参数不够熟悉,初期确实容易出错。
OK!全部完成了。但我想强调的并非具体代码,而是一种处理经验的积累。
最重要的是一种经验的掌握。当你面对大量的数据时千万不要紧张,它们也是小数据构成的,只要冷静下来,你就能想到方法来解决。这才是我想说的!!!与君共勉。
总结与心得
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对本站的支持。
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













