Pandasのカテゴリ型

Pandasのカテゴリ型をうまく使うとことで、シンプルで効率の良いデータ加工ができます。

unique()関数

Seriesデータを作成

import numpy as np
import pandas as pd

values = pd.Series(['Apple','Orange','Apple','Apple']*2)
values

結果
0 Apple
1 Orange
2 Apple
3 Apple
4 Apple
5 Orange
6 Apple
7 Apple
dtype: object

引数に配列を指定すると、ユニークな値の配列を返します。

pd.unique(values)

array([‘Apple’, ‘Orange’], dtype=object)

value_count()

配列の値の数を個別の数量を返します。

pd.value_counts(values)

結果
Apple 6
Orange 2
dtype: int64

values = pd.Series([0,1,0,0]*2)
dim = pd.Series(['Apple','Orange'])
values

結果
0 0
1 1
2 0
3 0
4 0
5 1
6 0
7 0
dtype: int64

dim

結果
0 Apple
1 Orange
dtype: object

val = dim.take(values)
val

結果
0 Apple
1 Orange
0 Apple
0 Apple
0 Apple
1 Orange
0 Apple
0 Apple
dtype: object

print(val[1])

結果
1 Orange
1 Orange
dtype: object

DataFrame型の活用

簡単なデータフレーム型のデータを例にカテゴリ型の活用を考えます。

例として単純なデータフレームを作成します。

fruits = ['Apple','Orange','Apple','Apple','Apple','Orange','Apple','Apple']
N = len(fruits)
df = pd.DataFrame({'fruit':fruits,
                   'basket_id':np.arange(N),
                   'count':np.random.randint(3,15,size=N),
                   'weight':np.random.uniform(0,4, size=N)},
                  columns=['basket_id','fruit','count','weight'])
df

結果
basket_id fruit count weight
0 0 Apple 9 0.205357
1 1 Orange 6 0.253771
2 2 Apple 9 2.380660
3 3 Apple 6 1.838016
4 4 Apple 13 0.947020
5 5 Orange 13 1.849480
6 6 Apple 14 2.635134
7 7 Apple 4 1.445773

astype()を使用して’fruit’列をカテゴリ型に変換します。

fruit_cat = df['fruit'].astype('category')
fruit_cat

結果
0 Apple
1 Orange
2 Apple
3 Apple
4 Apple
5 Orange
6 Apple
7 Apple
Name: fruit, dtype: category
Categories (2, object): [Apple, Orange]

通常の列表示と同じ結果ですが、追加で、Categories (2, object): [Apple, Orange] の項目が表示されます。
複数の値があっても、実はAppleとOrangeというカテゴリ(ユニークな値)でできていることがわかります。

categoriesプロパティとcodesプロパティ

categoriesプロパティとcodesプロパティで「カテゴリ名」と「カテゴリ番号」を返してくれます。
このことを活用するとカテゴリ変数のエンコーディング を行うことも可能になります。

c.categories

結果
Index([‘Apple’, ‘Orange’], dtype=’object’)

c.codes

結果
array([0, 1, 0, 0, 0, 1, 0, 0], dtype=int8)

例えばタイタニックの問題で’Sex’列を数値化して新しい列の’sex_num’に入れる場合、次のようにすることができます。

train['sex_num'] = train['Sex'].astype('category').values.codes

ただ変換するだけで良いのなら、これをもっとスマートに行うには、Pandasのfactorize()関数を使えば簡単です。

train['sex_num'], _ = pd.factorize(train['Sex'])

機械学習的には、One-Hotエンコーディング化でPandasのget_dummies()を使う場合が多いと思いますが、Pandasのカテゴリ型の仕組みを理解しておくことは、柔軟にデータを組み直すことができる指針になるかもしれません。