Одно горячее кодирование категориальных функций - только разреженная форма

У меня есть фрейм данных, который имеет целочисленные и категориальные функции. Категориальные признаки бывают двух типов: числа и строки.

Мне удалось выполнить одно горячее кодирование столбцов, которые были целочисленными и категориальными, то есть числами. Я получаю сообщение об ошибке, когда пытаюсь выполнить горячее кодирование категориальных столбцов, которые являются строками.

ValueError: не удалось преобразовать строку в число с плавающей запятой: '13367cc6'

Поскольку фрейм данных огромен с высокой мощностью, я хочу преобразовать его только в разреженную форму. Я бы предпочел решение, использующее from sklearn.preprocessing import OneHotEncoder, поскольку я с ним знаком.

Я проверил и другие вопросы, но ни один из них не отвечает на то, что я спрашиваю.

data = [[623, 'dog', 4], [123, 'cat', 2],[623, 'cat', 1], [111, 'lion', 6]]

Приведенный выше фрейм данных содержит 4 строки и 3 столбца.

Имена столбцов - ['animal_id', 'animal_name', 'number']

Предположим, что animal_id и animal_name хранятся в пандах как категория, а число как int64 dtype.


person Aman    schedule 28.03.2017    source источник
comment
Можете ли вы предоставить небольшой набор воспроизводимых данных для выборки?   -  person MaxU    schedule 28.03.2017
comment
Добавил пример. Дайте мне знать, если вам понадобятся другие подробности.   -  person Aman    schedule 28.03.2017


Ответы (2)


Предполагая, что у вас есть следующий DF:

In [124]: df
Out[124]:
   animal_id animal_name  number
0        623         dog       4
1        123         cat       2
2        623         cat       1
3        111        lion       6

In [125]: df.dtypes
Out[125]:
animal_id         int64
animal_name    category
number            int64
dtype: object

сначала сохраните animal_name столбец (если он вам понадобится в будущем):

In [126]: animal_name = df['animal_name']

преобразовать animal_name столбец в категориальный (экономящий память) числовой столбец:

In [127]: df['animal_name'] = df['animal_name'].cat.codes.astype('category')

In [128]: df
Out[128]:
   animal_id animal_name  number
0        623           1       4
1        123           0       2
2        623           0       1
3        111           2       6

In [129]: df.dtypes
Out[129]:
animal_id         int64
animal_name    category
number            int64
dtype: object

Теперь OneHotEncoder должен работать:

In [130]: enc = OneHotEncoder()

In [131]: enc.fit(df)
Out[131]:
OneHotEncoder(categorical_features='all', dtype=<class 'numpy.float64'>,
       handle_unknown='error', n_values='auto', sparse=True)

In [132]: X = enc.fit(df)

In [134]: X.n_values_
Out[134]: array([624,   3,   7])

In [135]: enc.feature_indices_
Out[135]: array([  0, 624, 627, 634], dtype=int32)
person MaxU    schedule 28.03.2017
comment
Как выбрать несколько столбцов, которые необходимо преобразовать в категориальные (экономящие память) числовые столбцы. У меня есть около 100 столбцов в кадре данных, над которым будет выполняться эта операция. - person Aman; 28.03.2017
comment
Я могу подумать об использовании цикла for. Но есть ли другой выход? - person Aman; 28.03.2017
comment
@ Аман, рад, что смог помочь :) Что такое dtypes из этих 100 столбцов? - person MaxU; 28.03.2017
comment
Первоначально они были либо int64, либо object, но они должны быть категориальными, поэтому после вашего предложения я написал цикл for: для столбцов в столбцах: train [col] = train [col] .astype ('category'). Cat.codes.astype ( 'category') В приведенном выше коде столбцы обозначают нужные столбцы, которые необходимо преобразовать в категориальные. - person Aman; 28.03.2017
comment
@Aman, ваши строковые столбцы уже имеют тип category или object? Думаю, имеет смысл открыть новый вопрос, предоставить там образец набора данных и распечатать результат print(train.dtypes) для вашего реального DF ... - person MaxU; 28.03.2017
comment
Спасибо за помощь. Цикл for, который я использовал, был не очень медленным. Я могу улучшить код, но я думаю, что сейчас меня это устраивает, так как я работаю в крайний срок. - person Aman; 28.03.2017
comment
Привет! Я пытаюсь использовать это, чтобы преобразовать столбец с 22000 разных городов в 22000-мерное пространство. Когда я запускаю тот же код, что и у вас, я получаю: ValueError: не удалось преобразовать строку в float: 'Valdosta'. Что я должен делать? - person bernando_vialli; 13.06.2018
comment
@mkheifetz, я бы порекомендовал вам открыть новый вопрос и предоставить туда небольшой воспроизводимый образец данных и желаемый набор данных. Решения могут различаться в зависимости от типов данных, количества столбцов, которые необходимо преобразовать / векторизовать, и т. Д. - person MaxU; 13.06.2018

К вашему сведению, есть и другие мощные схемы кодирования, которые не добавляли большое количество столбцов в качестве кодирования onehot (на самом деле они вообще не добавляли никаких столбцов). Некоторые из них - это счетное кодирование, целевое кодирование. Подробнее см. Мой ответ здесь и мой ipynb здесь.

person Victor Luu    schedule 30.06.2020