dfの型を調べ、必要な型に変更する

最終更新日:2021/7/4

DataFrame(df)の型を調べ、必要に応じ、型を変更することはとても重要です。ここを理解できていないと、いつまでも欲しいデータが作れません。或いは、データを作るのに無駄な時間を割いてしまうことになります。

【説明すること】

  • 1. 型を確認する: df.dtypes
  • 2. 型を変換する: df.astype()
    • 2.1. int型、float型(数値)からobject型(文字列)への変換: int, float => object
    • 2.2 object型からint型, float型への変換: object => int, float
    • 2.3 datetime型への変換: df.to_datetime() : => datetime
    • 2.4 csvファイルのIndexをdatetime型で読み込む: pd.read_csv(parse_dates =True)

ここでは以下のcsvファイルをインポートして、コードを書いています。ファイルはリンク先からダウンロードするか、コピーして、ご自身でcsvファイルにしてください。
ダウンロードする際は、拡張子がデフォルトで.txtになるので、.csvに手入力して変更してください。

a003_002.csv

ValueDate clm0 clm1 clm2 clm3 clm4 clm5
2021/6/30 -0.0481 8 Hokkaido 0.741 Japan 0
2021/6/15 0.0057 6 Kyoto 0.501 Japan 1
2020/12/1 0.0268 2 Gifu 0.72 Japan AAA


pd.read_csv()で読み込むと、以下のようになります。

import pandas as pd
f1 = r'C:\Users\shilabo\Documents\SHiLABO_python\a003_002.csv'
df1 = pd.read_csv(f1)
# ValueDate clm0 clm1 clm2 clm3 clm4 clm5
#0 2021/6/30 -0.0481 8 Hokkaido 0.741 Japan 0
#1 2021/6/15 0.0057 6 Kyoto 0.501 Japan 1
#2 2020/12/1 0.0268 2 Gifu 0.720 Japan AAA

1. 型を確認する: df.dtypes

df.dtypesで全ての列の型が表示されます。なお、df.dtypes()ではありません。最後のカッコは不要です。

print(df1.dtypes)
#ValueDate object
#clm0 float64
#clm1 int64
#clm2 object
#clm3 float64
#clm4 object
#clm5 object


特定の列の型を確認したい場合には、df1[‘clm1’].dtypesのように列を指定すればいいです。

print(df1['clm1'].dtypes)
#int64

2. 型を変換する

df.astype()で型の変更・変換が可能です。以下で変更する型を指定します。


文字列型:str
int型(整数):int
float型(浮動小数点): float


datetime型への変更は、後で説明するdf.to_datetime()で行います。(2.3 datetime型への変換

コードは、受け皿を書かないと、元のdfは変更されません。元のdfも変更したい場合は、同じカラム名(列名)を指定して、

df1[‘clm1’] = df1[‘clm1’].astype(float)

と書きます。

df1['clm1'] = df1['clm1'].astype('float')
print(df1.dtypes)
#ValueDate object
#clm0 float64
#clm1 float64 #<=float64に変わった
#clm2 object
#clm3 float64
#clm4 object
#clm5 object


しかし、自由に型を変更できるわけではありません。例えば、文字列をfloatに変換する事はできません。エラーとなります。
ただし、後述するようにobject型の列が数値と文字列の混在で、文字列を除き、数値だけに絞り込んだ後であれば変更可能です。

2.1. int型、float型(数値)からobject型(文字列)への変換

※int, float => object

例えば、数値を文字列の数字にしたい場合があります。見た目はどちらも同じですが、与えられたデータの形式上、文字列の数字を扱う場合があります。
金融データの場合、4桁の証券コードにこの傾向が見られます。
この場合strを指定すれば、object型になります。

df2a['clm1'] = df2a['clm1'].astype(str)

まず、変更する前に同じfloatどうしの’clm1’と’clm3’の和が計算できることを見てみます。結果を新しいカラム’sum1’に入れます。

#和を計算して、結果を'sum1'カラムに入れる
df1['sum1'] = df1['clm1'] + df1['clm3']
# ValueDate clm0 clm1 clm2 clm3 clm4 clm5 sum1
#0 2021/6/30 -0.0481 8.0 Hokkaido 0.741 Japan 0 8.741
#1 2021/6/15 0.0057 6.0 Kyoto 0.501 Japan 1 6.501
#2 2020/12/1 0.0268 2.0 Gifu 0.720 Japan AAA 2.720


df['カラム名'].astype(str)とすれば、object型に変更されます。

df1['clm1'] = df1['clm1'].astype(str)
print(df1.dtypes)
#ValueDate object
#clm0 float64
#clm1 object #<=object型に変わった
#clm2 object
#clm3 float64
#clm4 object
#clm5 object
#sum1 float64


こうすると、上のような’clm1’と’clm3’の和は計算できず、エラーとなります。’clm1’はobject(文字列)で’clm3’が数値だからです。
しかし、object型にしたことで、文字列同志の結合が可能となります。
例えば、以下の’sum2’は、’clm1’に’A’を結合した文字列です。

df1['sum2'] = df1['clm1'] + 'A'
#object+floatなので、計算できないが、文字列の結合ができる。
#df1['sum2'] = df1['clm1'] + df1['clm3']は不可。
# ValueDate clm0 clm1 clm2 clm3 clm4 clm5 sum1 sum2
#0 2021/6/30 -0.0481 8.0 Hokkaido 0.741 Japan 0 8.741 8.0A
#1 2021/6/15 0.0057 6.0 Kyoto 0.501 Japan 1 6.501 6.0A
#2 2020/12/1 0.0268 2.0 Gifu 0.720 Japan AAA 2.720 2.0A

2.2 object型からint型, float型への変換

※object => int, float

文字列と数値が混在しているとobject型となり、このままではint型やfloat型への変換はできません。しかし、文字列を除いた後であれば可能です。
以下では、列’clm5’の最後が’AAA’の文字列のため、object型となっています。しかし、’AAA’を除いた後のdfであれば、変換が可能です。
df2はdf1の最終行を除いてコピーしたもので、この時点では’clm5’はobject型が引き継がれています。

df2['clm5'] = df2['clm5'].astype(float)

でfloat型に変化すると、エラーは発生せず、float型になります。
以下では、最終行を除いて、df2にdf1を コピーします。すると、df2にdf1の’AAA’は含まれません。

#2.2. object型をfloat型に変換
df2 = df1.iloc[:-1,:7] #df1を最終行を除いてコピー ":-1"は最終行を除いて上全行、":7"は0~6列、という意味。
# ValueDate clm0 clm1 clm2 clm3 clm4 clm5
#0 2021/6/30 -0.0481 8.0 Hokkaido 0.741 Japan 0
#1 2021/6/15 0.0057 6.0 Kyoto 0.501 Japan 1


最初に、この状態での型を確認します。’clm5’はdf1の型であるobject型を引き継いでいます。

print(df2.dtypes)
#--- #df2.dtypes ---
#ValueDate object
#clm0 float64
#clm1 object
#clm2 object
#clm3 float64
#clm4 object
#clm5 object #<この時点ではobject型を引き継ぐ


ここで’clm5’をfloat型に変更します。dtypes()でfloat型に変更されているのがわかります。

df2['clm5'] = df2['clm5'].astype(float)
print(df2.dtypes)
#ValueDate object
#clm0 float64
#clm1 object
#clm2 object
#clm3 float64
#clm4 object
#clm5 float64 #<=float型に変わった


その証拠に、’clm0’と’clm5’の和を新しいカラム’sum3’に入れる、という操作を行うと、エラーとならず、計算が可能です。

df2['clm5'] = df2['clm5'].astype(float)
print(df2.dtypes)
#ValueDate object
#clm0 float64
#clm1 object
#clm2 object
#clm3 float64
#clm4 object
#clm5 float64 #<=float型に変わった

2.3 datetime型への変換

※=>datetime

.to_datetime()を使い、カラム名を指定して、以下のように書きます。
df1['ValueDate'] = pd.to_datetime(df1['ValueDate'])

datatime型への変更は.astype()では出来ません。

df1['ValueDate'] = pd.to_datetime(df1['ValueDate'])
print(df1.dtypes)
#ValueDate datetime64[ns] #<=datetimeに変わった。
#clm0 float64
#clm1 object
#clm2 object
#clm3 float64
#clm4 object
#clm5 object
#sum1 float64
#sum2 object


datetime型のどこがいいのか?
詳細は他のセクションで説明しますが、datetime型にして、それをindexに用いると、コードが簡素になり、とても便利です。
株価など、時系列データを扱う場合には、indexをdatetime型にする、は定石です。

2.4 csvファイルのIndexをdatetime型で読み込む

株価などの、元のファイルに日付が入った時系列データを扱う場合は、pd.read_csv()で読み込む際に、datetime型でindexにしてしまうと楽です。

これは、pd.read_csv()のオプションで、indexにするカラム(列)をindex_col=0(列番号)または” index_col=’ValueDate’(列名)を指定して、parse_dates=Trueを指定します。

df3a = pd.read_csv(f1, index_col=0, parse_dates=True)
df3b = pd.read_csv(f1, index_col='ValueDate', parse_dates=True)