日付として認識できない文字列などが入っていると陥るエラーです。
地味にハマったりするので記事にまとめました。
DataFrame作成時に、日付文字列の間に「日付ではない値」が入っているとobjectとして読み込まれます。
(なお、すべて日付として解釈可能な文字列で構成されている場合は、datetimeとして読み込めます。)
たとえば、実データでよくあるケースとして、日付の間に、ハイフン(-)を入れている等です。
temp = pd.DataFrame(["2020-04-09", "2020-04-10", "-", "2020-04-12"], columns=["date"])
date | |
---|---|
0 | 2020-04-09 |
1 | 2020-04-10 |
2 | - |
3 | 2020-04-12 |
このとき、datetime型への変換を行うとするとエラーとなります。
pd.to_datetime(temp.date)
# エラー出力
TypeError: Unrecognized value type: <class 'str'>
対策は下記のとおりです。
強制的にpd.to_datetime()を実行する
変換エラーを無視して実行します。
その際、変換NGの箇所は「NaT」となります。
pd.to_datetime(temp.date, errors="coerce")
# 変換結果
0 2020-04-09
1 2020-04-10
2 NaT
3 2020-04-12
Name: date, dtype: datetime64[ns]
今回のように、ハイフンが入っていてそれを無視することを、前もって理解している上であれば問題ないと思います。
しかし、よく分からないがエラーが出たので使用する、というのは避けたほうが良いかもしれません。
pd.to_datetime()実行前にデータを正す
事前に不要な文字列を、正しく置き換える、または除去します。
または、データファイルやDBの段階で対処しておきます。
例えば、ハイフンを空文字に置き換えてから実行してやります。
(空文字の場合は、pd.to_datetime()は例外を飛ばさずに実行をやりきれます。)
上記の強制実行と同様に、変換NGの箇所は「NaT」となります。
temp.date = temp.date.replace({"-":""})
pd.to_datetime(temp.date)
# 変換結果
0 2020-04-09
1 2020-04-10
2 NaT
3 2020-04-12
Name: date, dtype: datetime64[ns]
不正箇所を特定する簡単な方法
上記の例では、データが少ないためハイフンが紛れ込んでいることがすぐに分かりますが、データが大量になると把握が難しくなります。
例えば下記のコードで、お手軽に不正文字がチェックができます。
最初の不正箇所で例外が発生します。
全てチェックするには、引っかかった箇所を都度修正しながらチェックを繰り返すイメージとなります。
(あまりにも不正のバリエーションが多い場合は、途方も無い作業になるかもしれないので留意ください。)
def check(x):
print(x)
pd.to_datetime(x)
temp.date.map(check)
以上です。