パンダのカテゴリカル列を一括変換する(ワンホットエンコーディングではない)


12

私は大量のカテゴリー列を含むpandasデータフレームを持っています。これをscikit-learnの決定木で使用する予定です。それらを数値に変換する必要があります(1つのホットベクトルではありません)。scikit-learnのLabelEncoderでそれを行うことができます。問題は、それらが多すぎて手動で変換したくないことです。

このプロセスを自動化する簡単な方法は何でしょうか。


パンダのget_dummies関数が役立ちます。詳細については、こちらのドキュメントを確認してください。私はそれがこのユースケースを完全にカバーしていると思います、そしてあなたはカスタム接頭辞を提供することによって振る舞いをさらに微調整することができます。
hssay 2016

回答:


11

カテゴリー列が現在文字/オブジェクトである場合、次のようなものを使用してそれぞれを行うことができます。

char_cols = df.dtypes.pipe(lambda x: x[x == 'object']).index

for c in char_cols:
    df[c] = pd.factorize(df[c])[0]

カテゴリに戻る必要がある場合は、エンコーディングを保存するための辞書を作成します。何かのようなもの:

char_cols = df.dtypes.pipe(lambda x: x[x == 'object']).index
label_mapping = {}

for c in char_cols:
    df[c], label_mapping[c] = pd.factorize(df[c])

Julienのmcveを使用すると、次のように出力されます。

In [3]: print(df)
Out[3]: 
    a   b   c   d
0   0   0   0   0.155463
1   1   1   1   0.496427
2   0   0   2   0.168625
3   2   0   1   0.209681
4   0   2   1   0.661857

In [4]: print(label_mapping)
Out[4]:
{'a': Index(['Var2', 'Var3', 'Var1'], dtype='object'),
 'b': Index(['Var2', 'Var1', 'Var3'], dtype='object'),
 'c': Index(['Var3', 'Var2', 'Var1'], dtype='object')}

object列を見つけるためのコードは便利です。
javadba 2018

6

まず、遊ぶmcveを作成しましょう:

import pandas as pd
import numpy as np

In [1]: categorical_array = np.random.choice(['Var1','Var2','Var3'],
                                             size=(5,3), p=[0.25,0.5,0.25])
        df = pd.DataFrame(categorical_array,
               columns=map(lambda x:chr(97+x), range(categorical_array.shape[1])))
        # Add another column that isn't categorical but float
        df['d'] = np.random.rand(len(df))
        print(df)

Out[1]:
      a     b     c         d
0  Var3  Var3  Var3  0.953153
1  Var1  Var2  Var1  0.924896
2  Var2  Var2  Var2  0.273205
3  Var2  Var1  Var3  0.459676
4  Var2  Var1  Var1  0.114358

これで、pd.get_dummiesを使用して最初の3列をエンコードできます。

可能性を完全に説明するにはダミーで十分であるdrop_firstため、私はパラメーターを使用していることに注意してくださいN-1N(例:a_Var2a_Var30の場合、それはa_Var1)。また、具体的に列を指定していますが、dtype objectまたはcategorical(以下でさらに詳しく)のいずれかを持つ列になるため、指定する必要はありません。

In [2]: df_encoded = pd.get_dummies(df, columns=['a','b', 'c'], drop_first=True)
        print(df_encoded]
Out[2]:
          d  a_Var2  a_Var3  b_Var2  b_Var3  c_Var2  c_Var3
0  0.953153       0       1       0       1       0       1
1  0.924896       0       0       1       0       0       0
2  0.273205       1       0       1       0       1       0
3  0.459676       1       0       0       0       0       1
4  0.114358       1       0       0       0       0       0

特定のアプリケーションでは、カテゴリである列のリストを提供するか、カテゴリである列を推測する必要があります。

ベストケースシナリオ、あなたのデータフレームは、既にこれらの列がありdtype=category、あなたが渡すことができますcolumns=df.columns[df.dtypes == 'category']get_dummies

それ以外の場合dtypeは、他のすべての列を適切に設定することをお勧めします(ヒント:pd.to_numeric、pd.to_datetimeなど)。dtypeの列がobject残り、これらはカテゴリー列になります。

pd.get_dummiesパラメータ列のデフォルトは次のとおりです。

columns : list-like, default None
    Column names in the DataFrame to be encoded.
    If `columns` is None then all the columns with
    `object` or `category` dtype will be converted.

2

複数の列のタイプを一度に変換するには、次のようなものを使用します。

df2 = df.select_dtypes(include = ['type_of_insterest'])

df2[df2.columns].apply(lambda x:x.astype('category'))

それから私はそれらに戻って参加しますoriginal df


df2[df2.columns] = df2[df2.columns].astype('category')も同じだと思います、いやapply、いやlambda
パルペリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.