pandasのastype、to_datetimeメソッドで列を型変換(キャスト)する

pandas.Seriesは1つのデータ型dtypepandas.DataFrameは各列ごとにデータ型dtypeを持っています。

各列に対して、要約統計量を求めたり文字列メソッドや時系列メソッドを使用したりするとき、列のデータ型が正しくないとそれらのメソッドは正常に動作しません。

つまり、前処理をしたり集計したりするときは、列のdtypeを目的に沿ったデータ型に変換する必要があるという訳です。


この記事では

  • 時系列以外に型変換するastypeメソッド
  • 時系列に型変換するto_datetimeメソッド

について、サンプルコードを添えて紹介します。

時系列以外に変換|astypeメソッド

列のdtypeを時系列データ以外に変換するときは、pandas.Series.astypeメソッドを使用します。

この章では、以下のデータフレームを使用し、各列を時系列データ以外の型に変換します。

サンプル
import pandas as pd

df = pd.DataFrame(
    data={
        'a': [1, 4, 9, 16, 25],
        'b': [2.4, 5.1, 10.3, 17.9, 26.0],
        'c': [0, 1, np.nan, 2, None],
        'd': [True, True, False, False, True],
    })

print(df.to_markdown())
# |    |   a |     b |     c | d     |
# |---:|----:|------:|------:|:------|
# |  0 |   1 |   2.4 |   0.0 | True  |
# |  1 |   4 |   5.1 |   1.0 | True  |
# |  2 |   9 |  10.3 |   NaN | False |
# |  3 |  16 |  17.9 |   2.0 | False |
# |  4 |  25 |  26.0 |   NaN | True  |

pandas.DataFrame.dtypesでデータフレームの各列はint型やfloat型、bool型で格納されていることが確認できます。

print(df.dtypes)
# a      int64
# b    float64
# c    float64
# d       bool
# dtype: object

整数型に変換

astypeメソッドのdtypeパラメータに'int'を指定すると、データフレームの列(シリーズ)が整数型に変換されます。dtypeパラメータは省略可能。

  • float型→int型:小数点切り捨て
  • bool型→int型:True1False0に変換
  • 変換前のシリーズの要素に欠損値が含まれるとエラー

浮動小数点型→整数型

float型にastype('int')を指定すると、小数点は切り捨てられます。小数点を切り捨てたい前処理のときに役立ちます。

float型→int型
print(df['b'])
# 0     2.4
# 1     5.1
# 2    10.3
# 3    17.9
# 4    26.0
# Name: b, dtype: float64

# int型に変換
print(df['b'].astype('int'))
# 0     2
# 1     5
# 2    10
# 3    17
# 4    26
# Name: b, dtype: int64

ブール型→整数型

bool型にastype('int')を指定すると、True1False0に変換します。

bool型→int型
print(df['d'])
# 0     True
# 1     True
# 2    False
# 3    False
# 4     True
# Name: d, dtype: bool

# int型に変換
print(df['d'].astype('int'))
# 0    1
# 1    1
# 2    0
# 3    0
# 4    1
# Name: d, dtype: int64

変換前のシリーズの要素に欠損値が含まれるとエラー

シリーズの要素に欠損値が含まれる
print(df['c'])
# 0    0.0
# 1    1.0
# 2    NaN
# 3    2.0
# 4    NaN
# Name: c, dtype: float64

# int型に変換
print(df['c'].astype('int'))
# ValueError: Cannot convert non-finite values (NA or inf) to integer

浮動小数点型に変換

astypeメソッドのdtypeパラメータに'float'を指定すると、データフレームの列(シリーズ)が浮動小数点型に変換されます。実務であんまり使うことは無いかな。

  • int型→float型:小数点第1位に0を付ける
  • bool型→float型:True1.0False0.0に変換

整数型→浮動小数点型

int型にastype('float')を指定すると、小数点第1位に0が付与されます。

int型→float型
print(df['a'])
# 0     1
# 1     4
# 2     9
# 3    16
# 4    25
# Name: a, dtype: int64

# float型に変換
print(df['a'].astype('float'))
# 0     1.0
# 1     4.0
# 2     9.0
# 3    16.0
# 4    25.0
# Name: a, dtype: float64

ブール型→浮動小数点型

bool型にastype('float')を指定すると、True1.0False0.0に変換します。

bool型→float型
print(df['d'])
# 0     True
# 1     True
# 2    False
# 3    False
# 4     True
# Name: d, dtype: bool

# float型に変換
print(df['d'].astype('float'))
# 0    1.0
# 1    1.0
# 2    0.0
# 3    0.0
# 4    1.0
# Name: d, dtype: float64

文字列型に変換

astypeメソッドのdtypeパラメータに'str'を指定すると、データフレームの列(シリーズ)が文字列型に変換されます。

実務では、数値やブール型の列に対して文字列メソッドを使用したいときなどにしています。この型変換が一番使うかな。

欠損値は'nan''NaT'という文字列に置き換わるので、欠損値関係のメソッドが使えません。欠損値に対して何らかの処理を行いたい場合は、キャストする前に行っておきましょう。

欠損値は文字列に変換される
print(df['c'])
# 0    0.0
# 1    1.0
# 2    NaN
# 3    2.0
# 4    NaN
# Name: c, dtype: float64

print(df['c'].astype('str'))
# 0    0.0
# 1    1.0
# 2    nan
# 3    2.0
# 4    nan
# Name: c, dtype: object

print(df['c'].astype('str').apply(type))
# 0    <class 'str'>
# 1    <class 'str'>
# 2    <class 'str'>
# 3    <class 'str'>
# 4    <class 'str'>
# Name: c, dtype: object

ブール型に変換

astypeメソッドのdtypeパラメータに'bool'を指定すると、データフレームの列(シリーズ)がブール型に変換されます。0以外をTrue0Falseに変換します。

※欠損値はTrueに変換されるので、注意が必要です。

ブール型に変換
print(df['c'])
# 0    0.0
# 1    1.0
# 2    NaN
# 3    2.0
# 4    NaN
# Name: c, dtype: float64

# bool型に変換
print(df['c'].astype('bool'))
# 0    False
# 1     True
# 2     True
# 3     True
# 4     True
# Name: c, dtype: bool

複数列まとめて型変換

複数の列のdtypeを時系列データ以外に変換するときは、pandas.DataFrame.astypeメソッドを使用します。

列ごとに変換するdtypeを決めて、複数列まとめて型変換する

列ごとに変換するdtypeを決めて、複数列まとめて型変換
print(df.dtypes)
# a      int64
# b    float64
# c    float64
# d       bool
# dtype: object

# 列ごとに変換するdtypeを決めて、複数列まとめて型変換
print(df.astype({'a':'float', 'b':'int'}).dtypes)
# a    float64
# b      int64
# c    float64
# d       bool
# dtype: object

1つのdtypeで全ての列をまとめて型変換する

1つのdtypeで全ての列をまとめて型変換
print(df.dtypes)
# a      int64
# b    float64
# c    float64
# d       bool
# dtype: object

# bool型に変換
print(df.astype('bool').dtypes)
# a    bool
# b    bool
# c    bool
# d    bool
# dtype: object

時系列に変換|to_datetimeメソッド

日時(日付)の文字列や数値(シリアル値)を時系列データに変換するときは、pandas.to_datetimeメソッドを使用します。

この章では、以下のデータフレームを使用し、各列を時系列データに変換します。

サンプル
import pandas as pd

df = pd.DataFrame(
    data={
        'a':['2018-03-01 15:19:02', '2019-04-02 18:31:16', '2019-04-15 17:32:58'],
        'b':['2018-03-01', '2019-04-02', '2019-04-15'],
        'c':[43889, 43573, 43568],
    })

print(df.to_markdown())
# |    | a                   | b          |     c |
# |---:|:--------------------|:-----------|------:|
# |  0 | 2018-03-01 15:19:02 | 2018-03-01 | 43889 |
# |  1 | 2019-04-02 18:31:16 | 2019-04-02 | 43573 |
# |  2 | 2019-04-15 17:32:58 | 2019-04-15 | 43568 |

pandas.DataFrame.dtypesでデータフレームの各列はobject型やint型で格納されていることが確認できます。

print(df.dtypes)
# a    object
# b    object
# c     int64
# dtype: object

文字列をdatetime型に変換

日時(日付)の文字列が格納されている列を時系列データに型変換する場合、to_datetimeメソッドの引数にその列(シリーズ)を指定するだけで、時系列データに変換されたpandas.Seriesが返されます。

文字列→日時
df['a'] = pd.to_datetime(df['a'])
df['b'] = pd.to_datetime(df['b'])

print(df.dtypes)
# a    datetime64[ns]
# b    datetime64[ns]
# c             int64
# dtype: object

数値(シリアル値)をdatetime型に変換

シリアル値が格納されている列を時系列データに型変換する場合、to_timedeltaメソッドでシリアル値を日数に変換し、基準になる日付('1900-01-01')と足し合わせます。

シリアル値→日時
df['c'] = pd.to_timedelta(df['c'], unit='D') + pd.to_datetime('1900-01-01')

print(df.dtypes)
# a             object
# b             object
# c    timedelta64[ns]
# dtype: object
注意
このとき、ExcelやGoogleスプレッドシートからデータをインポートしている場合、基準となる日付が2日ずれて'1899-12-30'になることに気を付けましょう。