Pandas: конвертировать категории в номера
Предположим, что у меня есть блок данных со странами, которые идут как:
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, используя "факторы", поэтому я надеюсь, что pandas имеет что-то подобное.
Ответы
Ответ 1
Сначала измените тип столбца:
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)
Ответ 2
Если вы хотите преобразовать вашу серию в целочисленные идентификаторы, вы можете использовать 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
Ответ 3
Если вы используете библиотеку 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