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

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

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

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


この記事では

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

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

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

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

  • pandas.Series.astype — pandas 1.1.0 documentation
  • 構文
    pandas.Series.astype(dtype)
    
    # Return:
    #     Series: Series of same type as caller.
    逆引きdtypeパラメータに指定する値
    整数型に変換'int'
    浮動小数点型に変換'float'
    文字列型に変換'str'
    Pythonオブジェクト型に変換'object'
    ブール型に変換'bool'

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

    サンプル
    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メソッドを使用します。

  • pandas.DataFrame.astype — pandas 1.1.0 documentation
  • 構文
    # 列ごとに変換する型を決めて、複数列まとめて型変換する
    pandas.DataFrame.astype({'列名1':'dtype', '列名2':'dtype', …})
    
    # 1つの型で全ての列をまとめて型変換する
    pandas.DataFrame.astype(dtype)
    
    # Return:
    #     DataFrame: DataFrame of same type as caller.
    逆引きdtypeパラメータに指定する値
    整数型に変換'int'
    浮動小数点型に変換'float'
    文字列型に変換'str'
    Pythonオブジェクト型に変換'object'
    ブール型に変換'bool'

    列ごとに変換する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メソッドを使用します。

  • pandas.to_datetime — pandas 1.1.0 documentation
  • 構文
    pandas.to_datetime(Series)
    
    # Return:
    #     Series: Series of datetime64 dtype.

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

    サンプル
    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')と足し合わせます。

  • pandas.to_timedelta — pandas 1.1.0 documentation
  • シリアル値→日時
    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'になることに気を付けましょう。