แปลงข้อมูลหมวดหมู่ในดาต้าเฟรมแพนด้า


107

ฉันมีดาต้าเฟรมที่มีข้อมูลประเภทนี้ (มีคอลัมน์มากเกินไป):

col1        int64
col2        int64
col3        category
col4        category
col5        category

คอลัมน์มีลักษณะดังนี้:

Name: col3, dtype: category
Categories (8, object): [B, C, E, G, H, N, S, W]

ฉันต้องการแปลงค่าทั้งหมดในคอลัมน์เป็นจำนวนเต็มดังนี้:

[1, 2, 3, 4, 5, 6, 7, 8]

ฉันแก้ไขสิ่งนี้สำหรับหนึ่งคอลัมน์โดยสิ่งนี้:

dataframe['c'] = pandas.Categorical.from_array(dataframe.col3).codes

ตอนนี้ฉันมีสองคอลัมน์ในดาต้าเฟรม - เก่าcol3และใหม่cและจำเป็นต้องทิ้งคอลัมน์เก่า

นั่นเป็นการปฏิบัติที่ไม่ดี มันใช้งานได้ แต่ใน dataframe ของฉันมีหลายคอลัมน์และฉันไม่ต้องการทำด้วยตนเอง

pythonic นี้ทำอย่างไรและฉลาดแค่ไหน?

คำตอบ:


172

dataframe['c'].cat.codesประการแรกการแปลงคอลัมน์เด็ดขาดรหัสตัวเลขของคุณสามารถทำเช่นนี้ได้ง่ายขึ้นด้วย:
ต่อไปก็เป็นไปได้ที่จะเลือกโดยอัตโนมัติคอลัมน์ทั้งหมดที่มี dtype บางอย่างใน dataframe select_dtypesโดยใช้ ด้วยวิธีนี้คุณสามารถใช้การดำเนินการข้างต้นกับคอลัมน์หลายคอลัมน์ที่เลือกโดยอัตโนมัติ

ขั้นแรกให้สร้าง dataframe ตัวอย่าง:

In [75]: df = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),  'col3':list('ababb')})

In [76]: df['col2'] = df['col2'].astype('category')

In [77]: df['col3'] = df['col3'].astype('category')

In [78]: df.dtypes
Out[78]:
col1       int64
col2    category
col3    category
dtype: object

จากนั้นโดยใช้select_dtypesเพื่อเลือกคอลัมน์จากนั้นใช้.cat.codesกับแต่ละคอลัมน์เหล่านี้คุณจะได้รับผลลัพธ์ต่อไปนี้:

In [80]: cat_columns = df.select_dtypes(['category']).columns

In [81]: cat_columns
Out[81]: Index([u'col2', u'col3'], dtype='object')

In [83]: df[cat_columns] = df[cat_columns].apply(lambda x: x.cat.codes)

In [84]: df
Out[84]:
   col1  col2  col3
0     1     0     0
1     2     1     1
2     3     2     0
3     4     0     1
4     5     1     1

14
มีวิธีง่ายๆในการจับคู่ระหว่างรหัสหมวดหมู่และค่าสตริงหมวดหมู่หรือไม่
Allan Ruin

5
คุณสามารถใช้: df['col2'].cat.categoriesตัวอย่างเช่น
ogrisel

13
ชี้สำหรับทุกคนที่กังวลว่าสิ่งนี้จะจัดทำแผนที่NaNโดยไม่ซ้ำใคร-1
quietContest

2
รัก 2 สมุทร;)
Jose A

ระวังว่าหากมีการเรียงลำดับตามหมวดหมู่ (ลำดับ) รหัสตัวเลขที่ส่งคืนcat.codesอาจไม่ใช่รหัสที่คุณเห็นในซีรีส์!
paulperry


20

หากข้อกังวลของคุณเป็นเพียงการสร้างคอลัมน์พิเศษและลบในภายหลังเพียงแค่ใช้คอลัมน์ใหม่ในตอนแรก

dataframe = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),  'col3':list('ababb')})
dataframe.col3 = pd.Categorical.from_array(dataframe.col3).codes

คุณทำเสร็จแล้ว ขณะนี้Categorical.from_arrayเลิกใช้แล้วให้ใช้Categoricalโดยตรง

dataframe.col3 = pd.Categorical(dataframe.col3).codes

หากคุณต้องการการแมปย้อนกลับจากดัชนีไปยังป้ายกำกับก็มีวิธีที่ดีกว่านี้เช่นกัน

dataframe.col3, mapping_index = pd.Series(dataframe.col3).factorize()

ตรวจสอบด้านล่าง

print(dataframe)
print(mapping_index.get_loc("c"))

11

จำเป็นต้องแปลงหลายคอลัมน์ที่นี่ ดังนั้นแนวทางหนึ่งที่ฉันใช้คือ ..

for col_name in df.columns:
    if(df[col_name].dtype == 'object'):
        df[col_name]= df[col_name].astype('category')
        df[col_name] = df[col_name].cat.codes

สิ่งนี้จะแปลงคอลัมน์ประเภทสตริง / ออบเจ็กต์ทั้งหมดให้เป็นหมวดหมู่ จากนั้นใช้รหัสกับแต่ละประเภทของหมวดหมู่


3

สำหรับการแปลงข้อมูลหมวดหมู่ในคอลัมน์Cของข้อมูลชุดข้อมูลเราจำเป็นต้องดำเนินการดังต่อไปนี้:

from sklearn.preprocessing import LabelEncoder 
labelencoder= LabelEncoder() #initializing an object of class LabelEncoder
data['C'] = labelencoder.fit_transform(data['C']) #fitting and transforming the desired categorical column.

2

สิ่งที่ฉันทำคือฉันเห็นreplaceคุณค่า

แบบนี้-

df['col'].replace(to_replace=['category_1', 'category_2', 'category_3'], value=[1, 2, 3], inplace=True)

ด้วยวิธีนี้หากcolคอลัมน์มีค่าตามหมวดหมู่คอลัมน์เหล่านี้จะถูกแทนที่ด้วยค่าตัวเลข


1

@ Quickbeam2k1 ดูด้านล่าง -

dataset=pd.read_csv('Data2.csv')
np.set_printoptions(threshold=np.nan)
X = dataset.iloc[:,:].values

ใช้ sklearn ป้อนคำอธิบายภาพที่นี่

from sklearn.preprocessing import LabelEncoder
labelencoder_X=LabelEncoder()
X[:,0] = labelencoder_X.fit_transform(X[:,0])

3
ทำไมคุณไม่แก้คำตอบก่อนหน้าของคุณ? น่าแปลกที่คุณกำลังใช้fit_transformตอนนี้แทนtransform_fitและแก้ไขคำจำกัดความของ labelencoder ทำไมคุณถึงใช้iloc[:,:]? สิ่งนี้ไม่มีประโยชน์ เหตุผลเบื้องหลังภาพคืออะไร? ในกรณีที่คุณต้องการพิสูจน์ตัวฉันและ @theGtknerd ว่าคุณล้มเหลว
Quickbeam2k1

0

สำหรับคอลัมน์บางคอลัมน์หากคุณไม่สนใจเกี่ยวกับการสั่งซื้อให้ใช้สิ่งนี้

df['col1_num'] = df['col1'].apply(lambda x: np.where(df['col1'].unique()==x)[0][0])

หากคุณสนใจเกี่ยวกับการสั่งซื้อให้ระบุเป็นรายการและใช้สิ่งนี้

df['col1_num'] = df['col1'].apply(lambda x: ['first', 'second', 'third'].index(x))

0

วิธีที่ง่ายที่สุดวิธีหนึ่งในการแปลงตัวแปรจัดหมวดหมู่เป็นตัวแปรดัมมี่ / ตัวบ่งชี้คือการใช้get_dummies ที่แพนด้าให้มา ตัวอย่างเช่นเรามีข้อมูลซึ่งsexเป็นค่าตามหมวดหมู่ (เพศชายและเพศหญิง) และคุณต้องแปลงเป็นดัมมี่ / ตัวบ่งชี้นี่คือวิธีการทำ

tranning_data = pd.read_csv("../titanic/train.csv")
features = ["Age", "Sex", ] //here sex is catagorical value
X_train = pd.get_dummies(tranning_data[features])
print(X_train)

Age Sex_female Sex_male
20    0          1
33    1          0
40    1          0
22    1          0
54    0          1


0

คุณสามารถทำได้น้อยกว่ารหัสด้านล่าง:

f = pd.DataFrame({'col1':[1,2,3,4,5], 'col2':list('abcab'),'col3':list('ababb')})

f['col1'] =f['col1'].astype('category').cat.codes
f['col2'] =f['col2'].astype('category').cat.codes
f['col3'] =f['col3'].astype('category').cat.codes

f

ป้อนคำอธิบายภาพที่นี่

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.