【Pandas】データフレームで列のデータ型を変換する方法を解説

データを分析するときは、正しいデータ型でデータを扱わないと、予期しない結果やエラーが出る可能性があります。

Pythonでデータ分析をするときはPandasをよく使いますが、Pandasでは読み込んだデータの型を自動で推定してくれます。このときの精度は高く、初期の時点でおかしなデータ型として読み込まれることはあまりないと思います。

ですが、分析プロセスの途中でデータ型の変換が必要になるというケースは稀ではありません。

今回は、Pandasでの基本的なデータ型とデータ型の変換方法を具体的なデータを使いながら見ていこうと思います。

Pandasにおけるデータ型

データ型はプログラミング言語がそのデータをどのように格納、操作するかを識別するための内部構造です。

例えば、1+1の結果は2を返しますが、”こんにちは”+”みなさん”の結果は”こんにちはみなさん”となります。このような処理の違いを識別するために用いるのがデータ型です。

Pandasでは以下のようなデータ型の種類があります。

Pandasの型Pythonの型用途
objectstr or mixed文字列や文字列と数値の混合型
int64int整数
float64float浮動小数点
boolbool真/偽
datetime64NA日付および時刻
timedelta[ns]NA2つの日時の差
categoryNA文字列のカテゴリ

PandasにおけるObject型は文字列型を指しますが、同時に複数のデータ型を含めることもできます。

ただし、1つの列に複数のデータ型の値を保持していると分析で困ることになります(後述します)。

使用するデータ

今回使用するデータは、以下リンクから取得したCSVファイルを使用します。

https://github.com/chris1610/pbpython/tree/master/data

import pandas as pd

df = pd.read_csv("input/sales_data_types.csv")
Customer NumberCustomer Name2016 2017 Percent GrowthJan UnitsMonthDayYearActive
010002Quest Industries$125,000.00$162,500.0030.00%5001102015Y
1552278Smith Plumbing$920,000.00$1,012,000.0010.00%7006152014Y
223477ACME Industrial$50,000.00$62,500.0025.00%1253292016Y
324900Brekke LTD$350,000.00$490,000.004.00%7510272015Y
4651029Harbor Co$15,000.00$12,750.00-15.00%Closed222014N

値は全て埋まっており、分析には使えそうなデータです。

Pandasでの処理

データ型を確認する

データを読み込んだところで、データフレームのデータ型を確認します。

データ型を確認するには、df.dtypesを使います。

df.dtypes

さて、各データ型はそれぞれふさわしいデータ型になっているのでしょうか?

  • “Customer Number”はint型の方がよさそう
  • “2016”および”2017″は数値型として扱いたい
  • “Percent Growth”と”Jan Units”も数値として扱いたい
  • “Month”, “Day”, “Year”は日付型で扱いたい
  • “Active”はYesかNoのbool型としたい

こんな感じで、分析するためのデータ型とはなっていないようです。なので、それぞれ目的のデータ型に変換する必要があります。

データ型を変換する(文字列→数値)

Pandasでデータ型を変換するにはdf.astype()を用います。

例として、”Customer Number”をint型に変換します。

df['Customer Number'] = df['Customer Number'].astype('int')
print(df.dtypes)

データ型が変換されていることがわかります。

目的の型に変換できないとき

同様にして、他の列も目的の型に変換していきます。次は”2016″を数値型に変換してみます。

df['2016'] = df['2016'].astype('float')

といきたいところですが、エラーが出てしまいました。

どうやら「$」や「,」が原因みたいです。数値として扱うにはこれらを取り除く必要がありそうです。

文字列の置換にはreplace()を使います。また、簡潔に表現するためにlambda関数を使用します。

lambda x: x.replace('$', '').replace(',', '')

また、”2016″の列全ての項目に上記のlanbda関数を適用する必要があります。df.apply()を使うと、各項目に引数に渡した関数の処理を実行することができます。

そして、最後にfloat型に変換します。

df['2016'] = df['2016'].apply(lambda x: x.replace('$', '').replace(',', '')).astype('float')

変換することができました。ちなみに”2016″の値はどうなっているのかというと、以下のようになっています。

Customer NumberCustomer Name20162017Percent GrowthJan UnitsMonthDayYearActive
010002Quest Industries125000$162,500.0030.00%5001102015Y
1552278Smith Plumbing920000$1,012,000.0010.00%7006152014Y
223477ACME Industrial50000$62,500.0025.00%1253292016Y
324900Brekke LTD350000$490,000.004.00%7510272015Y
4651029Harbor Co15000$12,750.00-15.00%Closed222014N

きれいな数値になっていることがわかります。

同様に”2017″、”Percent Growth”も数値に変換していきます。 “Percent Growth” は元の百分率より小数の値の方が扱いやすいので100で割っておきます。

df['2017'] = df['2017'].apply(lambda x: x.replace('$', '').replace(',', '')).astype('float')
df['Percent Growth'] = df['Percent Growth'].apply(lambda x: x.replace('%', '')).astype('float') / 100

“Jan Units”も同様に数値に変換していこうとすると、エラーが発生してしまいます。最後の項目が「Closed」となっており、数値変換できないためです。

こういったケースではdf.astype()ではなくpd.to_numeric()を用いることで、より柔軟に対応することができます。引数にerrors=”coerce”を追加することで、変換できない項目は欠損に変換することができます。

df['Jan Units'] = pd.to_numeric(df['Jan Units'], errors='coerce')
Customer NumberCustomer Name20162017Percent GrowthJan UnitsMonthDayYearActive
010002Quest Industries1250001625000.35001102015Y
1552278Smith Plumbing92000010120000.117006152014Y
223477ACME Industrial50000625000.251253292016Y
324900Brekke LTD3500004900000.047510272015Y
4651029Harbor Co1500012750-0.15nan222014N

欠損値も分析においては好ましくないので、何等か処置をする必要があります。今回は欠損を0で置き換える処理を追加します。

df["Jan Units"] = pd.to_numeric(df['Jan Units'], errors='coerce').fillna(0)
Customer NumberCustomer Name20162017Percent GrowthJan UnitsMonthDayYearActive
010002Quest Industries1250001625000.35001102015Y
1552278Smith Plumbing92000010120000.117006152014Y
223477ACME Industrial50000625000.251253292016Y
324900Brekke LTD3500004900000.047510272015Y
4651029Harbor Co1500012750-0.150222014N

データ型を変換する(文字列→日付)

次は”Month”、”Day”、”Year”を日付型に変換します。

日付型に変換するためには、年月日をまとめる必要があります。なので、元のデータフレームの列を日付型にするのではなく、新規に”Time”列を作成します。

日付型への変換は pd.to_datetime ()を用います。

df["Time"] = pd.to_datetime(df[['Month', 'Day', 'Year']])
Customer NumberCustomer Name20162017Percent GrowthJan UnitsMonthDayYearActiveTime
010002Quest Industries1250001625000.35001102015Y2015/1/10
1552278Smith Plumbing92000010120000.17006152014Y2014/6/15
223477ACME Industrial50000625000.251253292016Y2016/3/29
324900Brekke LTD3500004900000.047510272015Y2015/10/27
4651029Harbor Co1500012750-0.150222014N2014/2/2

“Time”列はdatetime型です。

データ型を変換する(文字列→bool型)

次は”Active”をbool型に変換します。変換するにあたり、numpy(np)を使用します。np.where()でどの条件を真(偽)とするかというルールを指定し、変換します。

以下では、”Y”をTrue、それ以外をFalseとします。

import numpy as np
df["Active"] = np.where(df["Active"] == "Y", True, False)
Customer NumberCustomer Name20162017Percent GrowthJan UnitsMonthDayYearActiveTime
010002Quest Industries1250001625000.35001102015TRUE2015/1/10
1552278Smith Plumbing92000010120000.17006152014TRUE2014/6/15
223477ACME Industrial50000625000.251253292016TRUE2016/3/29
324900Brekke LTD3500004900000.047510272015TRUE2015/10/27
4651029Harbor Co1500012750-0.150222014FALSE2014/2/2

データ型を見てみると、bool型に変換できていることがわかります。

変換後のデータフレームは以下のようになりました。

“Active”はTRUEとFALSEに変換されました。

処理をまとめる

これまでの処理は、PandasにCSVを読み込む際にまとめて記述することができます。

単純に型を変換するだけの列は引数dtypeに、加工処理を加える際は引数converterで処理を記述します。

import pandas as pd
import numpy as np

df = pd.read_csv("input/sales_data_types.csv",
                 dtype={'Customer Number':'int'},
                 converters={'2016': lambda x: float(x.replace('$', '').replace(',', '')),
                               '2017': lambda x: float(x.replace('$', '').replace(',', '')),
                               'Percent Growth': lambda x: float(x.replace('%', ''))/100,
                               'Jan Units': lambda x: pd.to_numeric(x, errors='coerce'),
                               'Active': lambda x: np.where(x == "Y", True, False)
                              })

こうすることで、各列でどのような変換処理をしているのかがわかりやすくなりますね。

Pythonでデータサイエンスするなら

Pythonでデータサイエンスをするなら、以下の書籍がおすすめです。Pandas、matplotlib、Numpy、scikit-learnといったデータサイエンスに必要なライブラリを、体系立てて一通り学ぶことができます。

ややお値段高めですが、これ1冊で十分という内容・ボリュームなので、損はしないと思います^^

初学者の方にはこちらもオススメです^^

まとめ

Pandasのデータフレームのデータフレームを変換する方法を紹介しました。例に挙げたデータのように、そのままでは分析に使えないといったケースは少なくありません。

分析を始めて思いもよらいないエラーを回避するためにも、最初にデータ型の確認、変換を実施してください。

ではでは👋