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)
用法与影响
我预计影响将是净正面的
- 人们代码中潜在的严重 bug 将被尽早捕获;
- 实际需要混合格式的用户仍然可以解析它们,但现在他们将被迫对此非常明确;
- 代码库将显著简化。
据我所知,不会引入任何 bug。
实现
whatsnew 说明如下:
在下一个主要版本 2.0 中,正在考虑进行一些较大的 API 更改,且不会进行正式的弃用流程。
我建议将此更改作为上述内容的一部分进行,因为
- 它只会帮助预防 bug,而不会引入任何 bug;
- 考虑到当前行为可能导致的严重 bug,再等 2 年到 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'
选项