最終更新日:2021/9/5

ダミー変数を使って、データを数値に置き換える方法を説明します。
ダミー変数とは、 「Yesを1、Noを0」のように、情報を数値に置き換えた変数です。その数字自体に意味はありません。しかし、情報を数値にするこで、扱いやすさが飛躍的に向上します。

【説明すること】

1. ダミー変数に置き換える(値が2つの場合)

0か1、の2つに分けられる場合はdf.map()(map関数)とラムダ関数(lambda関数)の組み合わせで処理するのが簡単です。

以下のcsvファイルを読み込んで例を挙げます。
ここでは、’m’ならば0、’f’ならば1と置き換えます。

a008_001a.csv

import pandas as pd
f1 = r'C:\Users\shilabo\Documents\SHiLABO_python\a008_001a.csv'
df1 = pd.read_csv(f1)
df1a = df1.copy() #df1をコピーする。Copied df1.
print(df1a)
# clm0 clm1 clm2
#0 A m one
#1 B f two
#2 B m three
#3 C f one
#4 C m two
#5 C f three
df1a['CLM1'] = df1a['clm1'].map(lambda x: 0 if x=='m' else 1)
print(df1a)
# clm0 clm1 clm2 CLM1
#0 A m one 0
#1 B f two 1
#2 B m three 0
#3 C f one 1
#4 C m two 0
#5 C f three 1

2. ダミー変数に置き換える(値が3つ以上の場合)

【方法1】

以下のように、2つの場合と同様に、ラムダ関数に式を追加していけば可能です。
この例は、’one’ならば1、’two’ならば2、’three’ならば3の場合です。

df['clm'].map(lambda x: 1 if x=='one' else ( 2  if x== 'two' else 3))

df1b = df1.copy() #df1をコピー。Copied to df1.
df1b['CLM2'] = df1b['clm2'].map(lambda x: 1 if x=='one' else ( 2 if x== 'two' else 3))
print(df1b)
# clm0 clm1 clm2 CLM2
#0 A m one 1
#1 B f two 2
#2 B m three 3
#3 C f one 1
#4 C m two 2
#5 C f three 3


【方法2】

しかし、わかりにくいので、3つ以上の場合は、関数を定義して、df.map()と組み合わせて、以下のように書いた方がいいでしょう。
関数を定義すると、以下のように書き換えられます。

df['clm'].map(func)

ポイントは、.map()の引数に書く関数名に()は不要、という点です。つまり、func()と書かないで、関数名だけfuncと書きます。

def cvt(x):
if x == 'one':
return 1
elif x == 'two':
return 2
elif x == 'three':
return 3
df1c = df1.copy()
df1c['CLM2'] = df1b['clm2'].map(cvt)
print(df1c)
# clm0 clm1 clm2 CLM2
#0 A m one 1
#1 B f two 2
#2 B m three 3
#3 C f one 1
#4 C m two 2
#5 C f three 3

3. ダミー変数で全体像を知る

ダミー変数の0か1をdf全体に割り当て、データの全体像を知る方法です。pd.get_dummies()を使って、

pd.get_dummies(df1[['clm0', 'clm1']])

と書きます。カラムはlistで指定します。
指定したカラムから、そこに含まれるデータ毎に新しいカラムを作り、その値ならば1のフラグを立ててくれます。
これで、1行ずつ、列ごとにデータを確認できます。全体像を知るのに便利で、この結果を元に、様々な角度からデータを見ることができます。
例えば、どのデータを計算の対象とするかを見極める為に使います。

df1_dmy1 = pd.get_dummies(df1[['clm0', 'clm1', 'clm2']])
print(df1_dmy1)
# clm0_A clm0_B clm0_C clm1_f clm1_m clm2_one clm2_three clm2_two
#0 1 0 0 0 1 1 0 0
#1 0 1 0 1 0 0 0 1
#2 0 1 0 0 1 0 1 0
#3 0 0 1 1 0 1 0 0
#4 0 0 1 0 1 0 0 1
#5 0 0 1 1 0 0 1 0


以下のように、.sum()で集計すると、どのデータが何個あるかが分かります。
これは、 df.groupby(['clm'])['clm'].count()) でも確認できます。
例えば、データを分ける事で、それがどの程度意味があるか、を確かめる事ができます。

print(df1_dmy1.sum())
#clm0_A 1
#clm0_B 2
#clm0_C 3
#clm1_f 3
#clm1_m 3
#clm2_one 2
#clm2_three 2
#clm2_two 2
print(df1.groupby(['clm0'])['clm0'].count())
#clm0
#A 1
#B 2
#C 3


【参考】
pandas.get_dummies() : pandas API reference
https://pandas.pydata.org/docs/reference/api/pandas.get_dummies.html