Pandas의 범주 형 열을 대량 변환 (원핫 인코딩 아님)


12

scikit-learn을 사용하여 의사 결정 트리에서 사용할 예정인 수많은 범주 열이있는 팬더 데이터 프레임이 있습니다. 그것들을 숫자 값으로 변환해야합니다 (핫 벡터가 아닌). scikit-learn의 LabelEncoder로 할 수 있습니다. 문제는 너무 많아서 수동으로 변환하고 싶지 않다는 것입니다.

이 프로세스를 자동화하는 쉬운 방법은 무엇입니까?


팬더의 get_dummies 함수가 도움이 될 수 있습니다. 자세한 내용은 여기에서 설명서를 확인하십시오 . 이 유스 케이스를 완벽하게 다루고 있으며 사용자 정의 접 두부를 제공하여 동작을 추가 조정할 수 있다고 생각합니다.
hssay

답변:


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열 을 찾는 코드 는 v 유용합니다.
javadba

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 를 사용하여 처음 세 열을 인코딩 할 수 있습니다 .

인형은 가능성 을 완전히 설명하기에 충분하기 drop_first때문에 매개 변수를 사용하고 있습니다N-1N (예 : if 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.
paulperry
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.