Pandasで日付項目をdatetime[ns]
型に変換し、日付型として扱う方法について解説します。
日付項目を読み込む
次のCSVファイルを特にオプションを指定せずに読み込みます。
date1 ,date2 ,date3 ,date4 ,date5 ,date6 ,date7
2020年12月31日,2020年6月9日,2020-12-31,2020-6-9,2020/12/31,2020/6/9,20201231
このファイルには4種類(うち3種類は0埋めありとなしの2パターン用意)の日付項目が設定されています。
import pandas as pd
df = pd.read_csv('test.csv')
各項目がどの型で読み込まれているかinfo
関数で確認します。
df.info()
yyyymmdd
形式はint64
型、それ以外はobject
型(str
型)で読み込まれているのがわかります。
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 1 entries, 0 to 0
Data columns (total 7 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 date1 1 non-null object
1 date2 1 non-null object
2 date3 1 non-null object
3 date4 1 non-null object
4 date5 1 non-null object
5 date6 1 non-null object
6 date7 1 non-null int64
dtypes: int64(1), object(6)
memory usage: 184.0+ bytes
日付型に変換する
日付項目を加工したり、年・月・日などを取り出しやすくするために、datetime64[ns]
型に変換しておくと便利です。
datetime64[ns]
型に変換するには、pandas.to_datetime
関数を使います。
df['datetime1'] = pd.to_datetime(df['date1'], format="%Y年%m月%d日")
df['datetime2'] = pd.to_datetime(df['date2'], format="%Y年%m月%d日")
df['datetime3'] = pd.to_datetime(df['date3'])
df['datetime4'] = pd.to_datetime(df['date4'])
df['datetime5'] = pd.to_datetime(df['date5'])
df['datetime6'] = pd.to_datetime(df['date6'])
df['datetime7'] = pd.to_datetime(df['date7'], format="%Y%m%d")
年月日形式の項目はformat
オプションを指定しないとエラーになります。また、yyyymmdd
形式はエラーにはなりませんが、値をナノ秒と見なして読み込むため、1970-01-01 00:00:00.020201231
のような値になってしまいます。こちらもformat
オプションの指定が必要です。
読み込み時に 日付型に変換する
読み込んでみてから、「あ、これ日付項目か」と気づく場合は前述の方法を使っていただければよいですが、事前にどれが日付項目かわかっている時は読み込む時に日付型として読み込む方が効率的です。
標準の日付パーサーで変換できる場合
yyyy-mm-dd
形式やyyyy/mm/dd
形式、yyyymmdd
形式の場合は標準の日付パーサーで変換できます。
次のような形式の CSVファイルの場合、
date ,average
2021/8/1,28.7
2021/8/2,28.6
2021/8/3,29.0
2021/8/4,29.5
2021/8/5,29.1
2021/8/6,29.1
2021/8/7,27.9
以下のようにすることで、項目date
を日付datetime64[ns]
型で読み込むことができます。
df = pd.read_csv('weather.csv',
dtype={"date": str},
parse_dates=["date"])
df.info()
直接dtype
にdatetime64
を指定するのではなく、一旦dtype
オプションではstr
型を指定して、parse_dates
オプションで日付型にしたい項目を指定して変換するというやり方になります。
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7 entries, 0 to 6
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 date 7 non-null datetime64[ns]
1 average 7 non-null float64
dtypes: datetime64[ns](1), float64(1)
memory usage: 240.0 bytes
日付パーサーを自作して変換する場合
年月日形式などPandasが用意している標準の日付パーサーで変換できない場合は日付パーサーを自作して指定することで日付変換ができるようになります。
次のようなCSVファイルの場合、
date, average
2021年8月1日,28.7
2021年8月2日,28.6
2021年8月3日,29.0
2021年8月4日,29.5
2021年8月5日,29.1
2021年8月6日,29.1
2021年8月7日,27.9
先ほどと同じコードで読み込むと、エラーは発生しませんが、datetime64[ns]
型には変換されません。
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7 entries, 0 to 6
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 date 7 non-null object
1 average 7 non-null float64
dtypes: float64(1), object(1)
memory usage: 240.0+ bytes
このような場合は、日付パーサーを自作し、date_parser
オプションで指定します。
from datetime import datetime
my_parser = lambda date: datetime.strptime(date, '%Y年%m月%d日')
df = pd.read_csv('weather.csv',
dtype={"date": str},
parse_dates=["date"],
date_parser=my_parser)
df.info()
先ほどとは異なり、datetime64[ns]
型に変換されていることが確認できます。
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 7 entries, 0 to 6
Data columns (total 2 columns):
# Column Non-Null Count Dtype
--- ------ -------------- -----
0 date 7 non-null datetime64[ns]
1 average 7 non-null float64
dtypes: datetime64[ns](1), float64(1)
memory usage: 240.0 bytes
pandas.datetime.strptime
を使用するサンプルを見かけると思いますが、pandas.datetime
は将来的に削除される予定ですので、今後はdatetime
を使用しましょう。
/var/folders/3r/qfsmvnsd5sz0qvf367p_d5j00000gp/T/ipykernel_83309/1860031930.py:1: FutureWarning: The pandas.datetime class is deprecated and will be removed from pandas in a future version. Import from datetime module instead.
my_parser = lambda date: pd.datetime.strptime(date, ‘%Y年%m月%d日’)