Pandasで日付項目を日付型として扱う

Pandasで日付項目を日付型として扱う

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()

直接dtypedatetime64を指定するのではなく、一旦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日’)

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次