PDEP-4: 一致的日期时间解析
- 创建日期: 2022 年 9 月 18 日
- 状态: 已实现
- 讨论: #48621
- 作者: Marco Gorelli
- 修订版本: 2
摘要
建议是
to_datetime
变得严格,并使用相同的日期时间格式解析其输入中的所有元素。该格式要么从第一个非 NaN 元素推断(如果用户未提供format
),要么从format
推断;infer_datetime_format
被弃用(因为它将成为严格版本的默认值);- 清楚地记录了非严格解析的简单解决方法。
动机和范围
Pandas 日期解析非常灵活,但可以说过于灵活 - 请参阅 https://github.com/pandas-dev/pandas/issues/12585 和链接的问题,了解这会导致多少混乱。Pandas 可以中途切换格式,虽然这已记录在案,但它经常违反用户的预期。
简单示例
In [1]: pd.to_datetime(['12-01-2000 00:00:00', '13-01-2000 00:00:00'])
Out[1]: DatetimeIndex(['2000-12-01', '2000-01-13'], dtype='datetime64[ns]', freq=None)
用户几乎肯定打算将数据读取为“1 月 12 日,1 月 13 日”。但是,它被读取为“12 月 1 日,1 月 13 日”。没有发出警告或错误。
目前,确保一致解析的唯一方法是显式传递 format=
。参数 infer_datetime_format
不严格,可以与 format
一起调用,并且仍然可能违反用户的预期
In [2]: pd.to_datetime(['12-01-2000 00:00:00', '13-01-2000 00:00:00'], infer_datetime_format=True)
Out[2]: DatetimeIndex(['2000-12-01', '2000-01-13'], dtype='datetime64[ns]', freq=None)
详细描述
具体来说,建议是
- 如果未指定
format
,pandas
将从第一个非NaN行推断格式,并根据该格式解析其余输入。错误将根据errors
参数处理 - 不会静默切换格式; infer_datetime_format
将被弃用;dayfirst
和yearfirst
将继续像现在一样工作;- 如果无法从第一个非NaN行推断格式,将抛出
UserWarning
,鼓励用户显式传入格式。请注意,这只会发生在无效输入(如'a'
(稍后会抛出ParserError
))或输入(如'00:12:13'
)上,这些输入目前会转换为''2022-09-18 00:12:13''
。
如果用户具有混合格式的日期,他们仍然可以使用灵活的解析并接受它带来的风险,例如
In [3]: pd.to_datetime(['12-01-2000 00:00:00', '13-01-2000 00:00:00'], format='mixed')
Out[3]: DatetimeIndex(['2000-12-01', '2000-01-13'], dtype='datetime64[ns]', freq=None)
或者,如果他们的日期都是ISO8601,
In [4]: pd.to_datetime(['2020-01-01', '2020-01-01 03:00'], format='ISO8601')
Out[4]: DatetimeIndex(['2020-01-01 00:00:00', '2020-01-01 03:00:00'], dtype='datetime64[ns]', freq=None)
使用和影响
我预计影响将是积极的
- 人们代码中潜在的严重错误将在早期被发现;
- 实际上想要混合格式的用户仍然可以解析它们,但现在他们必须明确地说明这一点;
- 代码库将明显简化。
据我所知,没有引入错误的可能性。
实现
whatsnew 笔记中写道
在下一个主要版本发布 2.0 中,正在考虑对几个较大的 API 进行更改,但没有正式的弃用。
我建议将此更改作为上述更改的一部分,因为
- 它只会帮助防止错误,不会引入任何错误;
- 鉴于当前行为可能导致的严重错误,等到 pandas 3.0.0 之后再过两年可能会造成很大损失。
请注意,这并不意味着要删除dateutil.parser
,因为它仍然会在guess_datetime_format
中使用。但是,根据此提案,后续行将使用推断的格式进行解析,而不是重复调用dateutil.parser
并冒着它静默切换格式的风险
最后,函数from pandas._libs.tslibs.parsing import guess_datetime_format
将在pandas.tools
下公开。
超出范围
我们可以通过使用元素的随机样本推断格式来使guess_datetime_format
更智能。
PDEP 历史
- 2022 年 9 月 18 日:初稿
- 2023 年 1 月 25 日:修改以提及
format='ISO8601'
和format='mixed'
选项