CUBE SUGAR CONTAINER

技術系のこと書きます。

Python: pandas でダミー変数を生成する

今回は pandas を使ってダミー変数を生成する方法について書く。 ダミー変数というのは、例えば国籍や性別といった名義尺度の説明変数を数値に変換する手法のこと。 名義尺度は順序関係を持たないので、単純に取りうる値に対して連番を振るようなやり方では上手くいかない。 そこで、特定の状態や状況について「あり・なし」や「Yes/No」を 01 で表現することになる。 具体例については後述する。

使った環境は次の通り。

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.13.3
BuildVersion:   17D102
$ python -V
Python 3.6.4
$ pip list --format=columns | grep pandas
pandas          0.22.0 

下準備

まずは pandas をインストールして Python の REPL を起動する。

$ pip install pandas
$ python

続いてサンプルとなる DataFrame オブジェクトを用意する。 内容としてはユーザ情報を模したものにした。

>>> import pandas as pd
>>> import numpy as np
>>> data = [
...     ('Alice', 10, 'F'),
...     ('Bob', 20, 'M'),
...     ('Carol', 30, 'O'),
...     ('Daniel', 40, 'M'),
...     ('Eric', 50, np.nan),
... ]
>>> columns = ['name', 'age', 'gender']
>>> df = pd.DataFrame(data, columns=columns)

できあがった DataFrame は次の通り。

>>> df
     name  age gender
0   Alice   10      F
1     Bob   20      M
2   Carol   30      O
3  Daniel   40      M
4    Eric   50    NaN

性別からダミー変数を生成する

先ほど確認した通りサンプルの DataFrame には性別が格納されている。 値については M が男性で F が女性、O はその他で NaN は不明を表している。 まずは、この性別からダミー変数を生成してみよう。

pandas には get_dummies() という、そのものずばりな関数が用意されている。 この関数に Series オブジェクト (カラム) を渡せばダミー変数を自動で作ってくれる。

>>> pd.get_dummies(df['gender'])
   F  M  O
0  1  0  0
1  0  1  0
2  0  0  1
3  0  1  0
4  0  0  0

ちゃんとカラムに格納されている内容を元に、それに該当する行だけ 1 になるダミー変数ができた。

生成されたダミー変数は DataFrame オブジェクトになっている。

>>> dummy_df = pd.get_dummies(df['gender'])
>>> type(dummy_df)
<class 'pandas.core.frame.DataFrame'>

生成したダミー変数を元に DataFrame と一緒に使いたいときは、次のようにして連結すれば良い。

>>> pd.concat([df, dummy_df], axis=1)
     name  age gender  F  M  O
0   Alice   10      F  1  0  0
1     Bob   20      M  0  1  0
2   Carol   30      O  0  0  1
3  Daniel   40      M  0  1  0
4    Eric   50    NaN  0  0  0

ところで、先ほどの例でどのダミー変数にもビットが立っていないものがあることに気づいただろうか? 具体的にはインデックス番号が 4 の Eric の行で、性別が NaN になっていた。 get_dummies() 関数はデフォルトでは NaN についてはダミー変数を作らない。 もし作りたいときは dummy_na オプションを True に指定しよう。

>>> pd.get_dummies(df['gender'], dummy_na=True)
   F  M  O  NaN
0  1  0  0    0
1  0  1  0    0
2  0  0  1    0
3  0  1  0    0
4  0  0  0    1

ダミー変数の名前に特定のプレフィックスを付与したいときは prefix オプションを指定する。

>>> pd.get_dummies(df['gender'], prefix='gender')
   gender_F  gender_M  gender_O
0         1         0         0
1         0         1         0
2         0         0         1
3         0         1         0
4         0         0         0

名前についてはダミー変数を生成した後からカラム名を変更しても構わない。

>>> dummy_df.columns = ['gender_f', 'gender_m', 'gender_o']
>>> dummy_df
   gender_f  gender_m  gender_o
0         1         0         0
1         0         1         0
2         0         0         1
3         0         1         0
4         0         0         0

自分でダミー変数を作ってみる

先ほどの例では get_dummies() 関数を使うことでカラムから自動でダミー変数を作る方法を紹介した。 とはいえ get_dummies() 関数を使うより自分で作ったほうが手っ取り早いこともある。

例えば 20 歳以上かを表すダミー変数 adult を作ってみることにしよう。 この場合、次のように年齢のカラムから真偽値を作って整数に変換すると楽にできる。

>>> adult = (df['age'] >= 20).astype(np.int64)

名前さえ直してやれば、ちゃんとお目当てのダミー変数ができている。

>>> adult.name = 'adult'
>>> adult
0    0
1    1
2    1
3    1
4    1
Name: adult, dtype: int64

あとは元の DataFrame と連結するだけ。

>>> pd.concat([df, adult], axis=1)
     name  age gender  adult
0   Alice   10      F      0
1     Bob   20      M      1
2   Carol   30      O      1
3  Daniel   40      M      1
4    Eric   50    NaN      1

ばっちり。

めでたしめでたし。

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理

Pythonによるデータ分析入門 ―NumPy、pandasを使ったデータ処理