PDEP-4: 一貫性のあるdatetimeパース

概要

提案内容は以下のとおりです。

動機と範囲

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)

詳細な説明

具体的には、提案は以下のとおりです。

ユーザーが日付を混合形式で持っている場合、柔軟なパースを使用し、それが伴うリスクを受け入れることができます。例:

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変更が検討されています。

上記の変更の一環としてこの変更を行うことをお勧めします。その理由は、

これはdateutil.parserを削除することを意味するものではありません。これはguess_datetime_format内で引き続き使用されます。しかし、この提案では、後続の行は推測された形式でパースされ、dateutil.parserを繰り返し呼び出して、形式が黙って切り替わるリスクを回避します。

最後に、関数from pandas._libs.tslibs.parsing import guess_datetime_formatは、pandas.toolsの下で公開されます。

範囲外

形式を推測するために要素のランダムサンプルを使用することで、guess_datetime_formatをよりスマートにすることができます。

PDEP履歴