มวลแปลงคอลัมน์เด็ดขาดใน Pandas (ไม่ใช่การเข้ารหัสแบบร้อนแรง)


12

ฉันมี dataframe นุ่นกับคอลัมน์เด็ดขาดมากมายซึ่งฉันกำลังวางแผนที่จะใช้ในต้นไม้การตัดสินใจกับ scikit- เรียนรู้ ฉันต้องการแปลงให้เป็นค่าตัวเลข ฉันสามารถทำได้ด้วย LabelEncoder จาก scikit-learn ปัญหาคือมีจำนวนมากเกินไปและฉันไม่ต้องการแปลงด้วยตนเอง

อะไรจะเป็นวิธีที่ง่ายในการทำให้กระบวนการนี้เป็นแบบอัตโนมัติ


ฟังก์ชัน 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])

ใช้ mcve ของ Julien จะเอาท์พุท:

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

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-1หุ่นเพียงพอที่จะอธิบายNความเป็นไปได้อย่างเต็มที่ (เช่น: ถ้าa_Var2และa_Var3เป็น 0 แล้วมัน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

ในแอปพลิเคชันเฉพาะของคุณคุณจะต้องระบุรายการคอลัมน์ที่เป็นหมวดหมู่หรือคุณจะต้องอนุมานว่าคอลัมน์ใดเป็นหมวดหมู่

สถานการณ์กรณีที่ดีที่สุด dataframe ของคุณมีคอลัมน์เหล่านี้แล้วdtype=categoryและคุณสามารถส่งcolumns=df.columns[df.dtypes == 'category']ต่อไปget_dummiesได้

มิฉะนั้นฉันขอแนะนำให้ตั้งค่าdtypeคอลัมน์อื่น ๆ ทั้งหมดตามความเหมาะสม (คำแนะนำ: pd.to_numeric, pd.to_datetime ฯลฯ ) และคุณจะเหลือคอลัมน์ที่มีobjectdtype ไว้และคอลัมน์เหล่านี้ควรเป็นคอลัมน์หมวดหมู่ของคุณ

คอลัมน์พารามิเตอร์ 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.