Перетворення категоріальних даних у фрейм даних pandas


102

У мене є кадр даних із даними цього типу (забагато стовпців):

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і потрібно скинути старі стовпці.

Це погана практика. Це працює, але в моєму фреймі даних багато стовпців, і я не хочу робити це вручну.

Як це пітонічно і просто розумно?

Відповіді:


164

По- перше, щоб перетворити категоричний стовпець його числові коди, ви можете зробити це легше з: dataframe['c'].cat.codes.
Крім того, можна автоматично вибрати всі стовпці з певним dtype у фреймі даних за допомогою select_dtypes. Таким чином, ви можете застосувати вищеописану операцію до декількох автоматично вибраних стовпців.

Спочатку зробивши приклад фрейму даних:

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
чи є простий спосіб отримати відображення між кодом категорії та значеннями рядків категорії?
Аллан Руїн

5
Ви можете використовувати: df['col2'].cat.categoriesнаприклад.
ogrisel

13
Вказуючи всім, кого турбує, що ця карта буде NaNунікально для-1
тихого конкурсу

2
Любіть 2 лайнери;)
Хосе А

Зверніть увагу, що якщо категоріальне впорядковано (порядковий), то числові коди, що повертаються, cat.codesНЕ можуть бути тими, які ви бачите в серії!
біднота


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і виправили визначення лабеленкодера. Чому ви використовуєте iloc[:,:]? це марно. У чому причина зображення? Якщо ви хотіли довести мене і @theGtknerd Wrond, вам не вдалося.
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))
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.