Панди: перетворення категорій у числа


86

Припустимо, у мене є фрейм даних із країнами, який називається:

cc | temp
US | 37.0
CA | 12.0
US | 35.0
AU | 20.0

Я знаю, що існує функція pd.get_dummies для перетворення країн на "гаряче кодування". Однак я хочу замість цього перетворити їх на індекси, які я отримаю cc_index = [1,2,1,3]замість цього.

Я припускаю, що існує швидший спосіб, ніж використання get_dummies разом із реченням numpy where, як показано нижче:

[np.where(x) for x in df.cc.get_dummies().values]

Це дещо простіше зробити в R, використовуючи 'фактори', тому я сподіваюся, що у панд є щось подібне.


2
Ви маєте на увазі cc_index = [0,1,0,2]?
juanpa.arrivillaga

1
звичайно, забув про індекс python 0
sachinruk

Можуть допомогти категоріальні ряди або стовпці в DataFrame.
min2bro

Відповіді:


150

Спочатку змініть тип стовпця:

df.cc = pd.Categorical(df.cc)

Тепер дані схожі, але зберігаються категорично. Щоб отримати коди категорій:

df['code'] = df.cc.cat.codes

Тепер у вас є:

   cc  temp  code
0  US  37.0     2
1  CA  12.0     1
2  US  35.0     2
3  AU  20.0     0

Якщо ви не хочете змінювати свій DataFrame, а просто отримуєте коди:

df.cc.astype('category').cat.codes

Або використовуйте категорійний стовпець як індекс:

df2 = pd.DataFrame(df.temp)
df2.index = pd.CategoricalIndex(df.cc)

5
df.cc.cat.codesЗдається, дзвінок змінився на просто df.cc.codes?
Андреас Сторвік Штрауман,

1
Зверніть увагу, що якщо у вас відсутні значення, вони будуть закодовані до -1. Якщо ви хочете уникнути розгляду цієї справи, спочатку можете передати на рядок: df.cc.astype ('str'). Astype ('category'). Cat.codes
Хлопець,

Здається, перетворити NaNяк -1?
ахбон

25

Якщо ви хочете лише перетворити свою серію на цілочисельні ідентифікатори, ви можете використовувати pd.factorize.

Зауважте, що це рішення, на відміну від pd.Categorical, не буде сортувати за алфавітом. Тож буде призначена перша країна 0. Якщо ви хочете почати з 1, ви можете додати константу:

df['code'] = pd.factorize(df['cc'])[0] + 1

print(df)

   cc  temp  code
0  US  37.0     1
1  CA  12.0     2
2  US  35.0     1
3  AU  20.0     3

Якщо ви хочете сортувати за алфавітом, вкажіть sort=True:

df['code'] = pd.factorize(df['cc'], sort=True)[0] + 1 

14

Якщо ви використовуєте sklearnбібліотеку, яку ви можете використовувати LabelEncoder. Як pd.Categorical, вхідні рядки сортуються за алфавітом перед кодуванням.

from sklearn.preprocessing import LabelEncoder

LE = LabelEncoder()
df['code'] = LE.fit_transform(df['cc'])

print(df)

   cc  temp  code
0  US  37.0     2
1  CA  12.0     1
2  US  35.0     2
3  AU  20.0     0

2

Спробуйте це, перетворіть у число на основі частоти (висока частота - велике число):

labels = df[col].value_counts(ascending=True).index.tolist()
codes = range(1,len(labels)+1)
df[col].replace(labels,codes,inplace=True)

1

Змінить будь-які стовпці на Numbers. Він не створить новий стовпець, а просто замінить значення числовими даними.

def characters_to_numb(*args): for arg in args: df[arg] = pd.Categorical(df[arg]) df[arg] = df[arg].cat.codes return df


0

Однорядковий код:

df[['cc']] = df[['cc']].apply(lambda col:pd.Categorical(col).codes)

Це працює також, якщо у вас є list_of_columns:

df[list_of_columns] = df[list_of_columns].apply(lambda col:pd.Categorical(col).codes)

Крім того, якщо ви хочете зберегти свої NaNзначення, ви можете застосувати заміну:

df[['cc']] = df[['cc']].apply(lambda col:pd.Categorical(col).codes).replace(-1,np.nan)
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.