こんにちは。カルークです。
今回はpandasのto_datetime()を使って、object型のカラムからdatetime型のカラムに変換する方法について記載します。その際、日付が独自のフォーマットで記述されている場合の対処方法についてもまとめます。
実行環境
今回の実行環境は以下になります。
- OS: Windows 10 Pro (64-bit)
- Anaconda: conda version 4.9.2
- Python: 3.8
- 実行環境: jupyter notebook
- pandas: 1.2.3
基本的な使い方
まずは基本的な使い方です。最初にpandasを忘れずにインポートしておきます。
import pandas as pd
以下のようなデータがあったとします。
df = pd.DataFrame({"birthday": ["2015-01-01", "2015-01-12", "2015-01-15"],
"name": ["tanaka", "sato", "suzuki"]})
df
型を確認してみると、どちらも文字列でobject型として認識されているようです。
df.dtypes
# 出力
birthday object
name object
dtype: object
それでは、pandasのto_datetime()関数を使って、birthdayのカラムをdatetime型に変換してみます。(ここでは、新たに作成したデータはそのままbirthdayカラムに上書きをしています)
df["birthday"] = pd.to_datetime(df["birthday"])
もう一度、型を確認してみましょう。
df.dtypes
# 出力
birthday datetime64[ns]
name object
dtype: object
birthdayがobject型からdatetime型に変換されている事が分かります。
dataframeを出力して、値も確認しておきます。
df
birthdayにちゃんと値が入っているのが分かります。
object型からdatetime型に変換されて何が嬉しいのか?
ここまでの説明だとデータの中身を見ても型がobjectからdatetime64型に変換されただけで、値も何も変わっていないように思えます。しかし、値がdatetime型として認識されたことにより、例えば年だけを取得したい、月だけを取得したい、日付だけを取得したいなどが行う事ができます。
「年」を取得したい:
df["birthday"].dt.year
# 出力
0 2015
1 2015
2 2015
Name: birthday, dtype: int64
「月」を取得したい:
df["birthday"].dt.month
0 1
1 1
2 1
Name: birthday, dtype: int64
「日」を取得したい:
df["birthday"].dt.day
0 1
1 12
2 15
Name: birthday, dtype: int64
使い方として、例えば以下のように.dtを使うことで、年・月・日だけを分離したカラムを新たに作成することが出来ます。
df["birthday-year"] = df["birthday"].dt.year
df["birthday-month"] = df["birthday"].dt.month
df["birthday-day"] = df["birthday"].dt.day
dfの中身を見てみると、年月日がそれぞれ別のカラムになっている事が分かります。
日付のカラムのフォーマットが独特な場合
先程はフォーマットを指定せずとも、pandasがいい感じにフォーマットを解釈してdatetime64型に変換をしてくれました。
ではこんなデータだとどうでしょうか。
df = pd.DataFrame({"birthday": ["y2015m01d01", "y2015m01d12", "y2015m01d15"],
"name": ["tanaka", "sato", "suzuki"]})
df
birthdayの記述の仕方が複雑そうですが、どうやら年の前には”y”、月の前には”m”、日の前には”d”が付くというルールのようです。
それでは先程と同様にto_datetimeでobject型からdatetime型に変換をしてみましょう。
df["birthday"] = pd.to_datetime(df["birthday"])
# 出力
df["birthday"] = pd.to_datetime(df["birthday"])
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
~\anaconda3\envs\test_env\lib\site-packages\pandas\core\arrays\datetimes.py in objects_to_datetime64ns(data, dayfirst, yearfirst, utc, errors, require_iso8601, allow_object)
2084 try:
-> 2085 values, tz_parsed = conversion.datetime_to_datetime64(data)
2086 # If tzaware, these values represent unix timestamps, so we
pandas\_libs\tslibs\conversion.pyx in pandas._libs.tslibs.conversion.datetime_to_datetime64()
TypeError: Unrecognized value type: <class 'str'>
During handling of the above exception, another exception occurred:
…
(長いので途中省略)
…
ParserError: Unknown string format: y2015m01d01
Unknown string formatというパースエラーが出てしまいました。フォーマットが上手く解釈できずにエラーになっているようです。
そんな時は以下のように日付カラムのフォーマットを指定してto_datetimeを実行してみます。
df["birthday"] = pd.to_datetime(df["birthday"], format="y%Ym%md%d")
今度はエラー無しで実行が出来ました。ちゃんと型変換されたかも見てみます。
df.dtypes
# 出力
birthday datetime64[ns]
name object
dtype: object
上手くdatetime64型に変換がなされました。中身も見てみますが問題なさそうです。
formatの指定方法
上記ではフォーマット指定の方法について詳しく説明しませんでしたが、基本的にはフォーマットの記述ルールを人が確認して指定する流れになります。例えば、”2015年12月11日”のフォーマットは、format=”%Y年%m月%d日”というように指定できます。
フォーマットの詳しい指定方法については公式ドキュメントに記載されています。
まとめ
今回はpandasのto_datetime()を使って、object型のカラムからdatetime型のカラムに変換する方法について基本的な使い方と合わせて、フォーマットを指定する方法についてもまとめました。