PDEP-4: 一貫した日時解析
- 作成日: 2022年9月18日
- ステータス: 実装済み
- 議論: #48621
- 著者: Marco Gorelli
- 改訂: 2
概要
提案は以下の通りです。
to_datetimeは厳格になり、入力内のすべての要素を解析するために同じ日時フォーマットを使用します。フォーマットは、(ユーザーがformatを指定しない場合) 最初の非 NaN 要素から推論されるか、formatから推論されます。infer_datetime_formatは非推奨になります (その厳格なバージョンがデフォルトになるため)。- 厳格でない解析の簡単な回避策が明確に文書化されます。
動機と範囲
Pandasの日付解析は非常に柔軟ですが、議論の余地があるほど柔軟すぎます。これがどれほどの混乱を引き起こしているかは、https://github.com/pandas-dev/pandas/issues/12585 および関連するissueを参照してください。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を発生させるでしょう) のような無効な入力、または現在'2022-09-18 00:12:13'に変換される'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 までさらに2年間待つことは、潜在的に多くの損害を引き起こす可能性があります。
これは 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'オプションに言及するよう修正