Я пытаюсь использовать scikit-learn's LabelEncoder
для кодирования панд DataFrame
строковых меток. Поскольку в фрейме данных есть много (более 50) столбцов, я хочу избежать создания LabelEncoder
объекта для каждого столбца; Я бы предпочел просто иметь один большой LabelEncoder
объект, который работает во всех моих столбцах данных.
Бросок всего DataFrame
в LabelEncoder
создает следующую ошибку. Пожалуйста, имейте в виду, что я использую фиктивные данные здесь; на самом деле я имею в виду около 50 столбцов данных с метками строк, поэтому нужно решение, которое не ссылается ни на один столбец по имени.
import pandas
from sklearn import preprocessing
df = pandas.DataFrame({
'pets': ['cat', 'dog', 'cat', 'monkey', 'dog', 'dog'],
'owner': ['Champ', 'Ron', 'Brick', 'Champ', 'Veronica', 'Ron'],
'location': ['San_Diego', 'New_York', 'New_York', 'San_Diego', 'San_Diego',
'New_York']
})
le = preprocessing.LabelEncoder()
le.fit(df)
Traceback (последний вызов был последним): файл "", строка 1, в файле "/Users/bbalin/anaconda/lib/python2.7/site-packages/sklearn/preprocessing/label.py", строка 103, в соответствии y = column_or_1d (y, warn = True) Файл "/Users/bbalin/anaconda/lib/python2.7/site-packages/sklearn/utils/validation.py", строка 306, в column_or_1d повышает ValueError ("неверная форма ввода { 0} ". Format (shape)) ValueError: неправильная форма ввода (6, 3)
Есть мысли о том, как обойти эту проблему?
источник
dataframe
строковых данных. Я выбираю объект (ы) кодирования, поэтому хочу избежать необходимости выбирать / удалять 50 отдельных объектов. Кроме того, мне интересно, есть ли способ, чтобы кодировщик упростил данные, то есть просто возвращал одну строку с идентификатором для каждой уникальной комбинации переменных в каждом столбце.replace
методу. Смотрите этот ответ нижеОтветы:
Вы можете легко сделать это, хотя,
EDIT2:
В scikit-learn 0.20 рекомендуемый способ
поскольку OneHotEncoder теперь поддерживает ввод строки. Применение OneHotEncoder только к определенным столбцам возможно с ColumnTransformer.
РЕДАКТИРОВАТЬ:
Так как этот ответ более года назад и вызвал много голосов (включая награду), я, вероятно, должен расширить это.
Для inverse_transform и transform вам придется немного взломать.
При этом вы теперь сохраните все столбцы в
LabelEncoder
качестве словаря.источник
df.apply(LabelEncoder().fit_transform)
?LabelBinarizer
вместо этого и повторно использовать словарь для набора тестов? Я пытался,d = defaultdict(LabelBinarizer)
а затем,fit = df.apply(lambda x: d[x.name].fit_transform(x))
но возникает исключениеException: Data must be 1-dimensional
. Я не уверен, как я ожидаю, что результирующий DataFrame будет выглядеть ... возможно, каждый столбец должен содержать бинаризованные векторы.Как упомянуто larsmans, LabelEncoder () принимает только 1-й массив в качестве аргумента . Тем не менее, довольно легко свернуть свой собственный кодировщик меток, который работает с несколькими столбцами по вашему выбору и возвращает преобразованный фрейм данных. Мой код здесь частично основан на отличном сообщении Зака Стюарта, найденном здесь .
Создание пользовательского кодировщика включает в себя просто создать класс , который реагирует на
fit()
,transform()
иfit_transform()
методу. В вашем случае хорошим началом может быть что-то вроде этого:Предположим, мы хотим закодировать два наших категориальных атрибута (
fruit
иcolor
), оставляя только числовой атрибутweight
. Мы могли бы сделать это следующим образом:Что преобразует наш
fruit_data
набор данных изв
Если передать ему фрейм данных, состоящий полностью из категориальных переменных, и пропустить этот
columns
параметр, то все столбцы будут закодированы (что, я полагаю, является тем, что вы изначально искали):Это превращает
в
,
Обратите внимание, что он, вероятно, захлебнется, когда попытается закодировать уже числовые атрибуты (добавьте некоторый код для обработки этого, если хотите).
Еще одна приятная особенность в том, что мы можем использовать этот специальный преобразователь в конвейере:
источник
Начиная с scikit-learn 0.20 вы можете использовать
sklearn.compose.ColumnTransformer
иsklearn.preprocessing.OneHotEncoder
:Если у вас есть только категориальные переменные,
OneHotEncoder
напрямую:Если у вас есть гетерогенно типизированные функции:
Дополнительные параметры в документации: http://scikit-learn.org/stable/modules/compose.html#columntransformer-for-heterogene-data
источник
inverse_transform()
не поддерживается в ColumnTransformer, хотя. По крайней мере, на данный момент: github.com/scikit-learn/scikit-learn/issues/11463 . Это большой недостаток для моего приложения, и, вероятно, будет также для других.Нам не нужен LabelEncoder.
Вы можете преобразовать столбцы в категории и затем получить их коды. Я использовал приведенное ниже словарное понимание, чтобы применить этот процесс к каждому столбцу и обернуть результат обратно в кадр данных той же формы с идентичными индексами и именами столбцов.
Чтобы создать словарь сопоставления, вы можете просто перечислить категории, используя словарь:
источник
это не дает прямого ответа на ваш вопрос (на что у Напутипулу Джона и ПрайсХардмана фантастические ответы)
Тем не менее, для целей нескольких задач классификации и т. Д. Вы можете использовать
это может вводить фрейм данных с категориальными данными и возвращать фрейм данных с двоичными значениями. значения переменных кодируются в имена столбцов в результирующем кадре данных. Больше
источник
Предполагая, что вы просто пытаетесь получить
sklearn.preprocessing.LabelEncoder()
объект, который можно использовать для представления ваших столбцов, все, что вам нужно сделать, это:В приведенном выше коде у вас будет уникальный номер, соответствующий каждому столбцу. Точнее, у вас будет 1: отображение 1 из
df.columns
вle.transform(df.columns.get_values())
. Чтобы получить кодировку столбца, просто передайте егоle.transform(...)
. Например, следующий код получит кодировку для каждого столбца:Предполагая, что вы хотите создать
sklearn.preprocessing.LabelEncoder()
объект для всех ваших меток строк, вы можете сделать следующее:В этом случае, скорее всего, у вас есть неуникальные метки строк (как показано в вашем вопросе). Чтобы увидеть, какие классы создал кодировщик, вы можете сделать
le.classes_
. Вы заметите, что это должно иметь те же элементы, что и вset(y for x in df.get_values() for y in x)
. Еще раз для преобразования метки строки в закодированную метку используйтеle.transform(...)
. Например, если вы хотите получить метку для первого столбца вdf.columns
массиве и первой строки, вы можете сделать это:Вопрос, который вы задали в своем комментарии, немного сложнее, но все еще может быть решен:
Приведенный выше код выполняет следующие действия:
LabelEncoder
класса, не поддерживающего кортежи в качестве имени класса.LabelEncoder
.Теперь использовать эту новую модель немного сложнее. Предполагая, что мы хотим извлечь представление для того же элемента, который мы искали в предыдущем примере (первый столбец в df.columns и первый ряд), мы можем сделать это:
Помните, что каждый поиск теперь является строковым представлением кортежа, который содержит (столбец, строку).
источник
Нет,
LabelEncoder
не делает этого. Он принимает 1-й массив меток класса и создает 1-й массив. Он предназначен для обработки меток классов в задачах классификации, а не в произвольных данных, и любая попытка использовать его в других целях потребует кода для преобразования фактической проблемы в проблему, которую она решает (и решение обратно в исходное пространство).источник
DataFrame
за раз?LabelEncoder
код и адаптируйте его. Я сам не пользуюсь пандами, поэтому не знаю, насколько это будет сложно.pandas
людям тоже разобраться в этом вопросе - я уверен, что я не единственный, кто столкнулся с этой проблемой, поэтому я надеюсь, что там может быть готовое решение.Это спустя полтора года после факта, но мне тоже нужно было иметь возможность
.transform()
одновременно создавать несколько столбцов панд данных (и у.inverse_transform()
них тоже). Это распространяется на превосходное предложение @PriceHardman выше:Пример:
Если
df
иdf_copy()
являютсяpandas
фреймами данных смешанного типа , вы можете применить ихMultiColumnLabelEncoder()
кdtype=object
столбцам следующим образом:Вы можете получить доступ к отдельным классам столбцов, меткам столбцов и кодировщикам столбцов, используемым для подгонки каждого столбца, с помощью индексации:
mcle.all_classes_
mcle.all_encoders_
mcle.all_labels_
источник
fit
метод сверху, который на самом деле не будет производить никаких ярлыков, пока вы не примените его (transform
/fit_transform
) к данные.Следуя комментариям к решению @PriceHardman, я бы предложил следующую версию класса:
Этот класс подходит для энкодера на тренировочном наборе и использует адаптированную версию при трансформации. Первоначальную версию кода можно найти здесь .
источник
Короткий путь к
LabelEncoder()
нескольким столбцам с помощьюdict()
:и вы можете использовать это
le_dict
для labelEncode любого другого столбца:источник
Все это можно сделать непосредственно в пандах и хорошо подходит для уникальной способности
replace
метода.Во-первых, давайте создадим словарь словарей, отображающих столбцы и их значения в новые замещающие значения.
Поскольку это всегда будет сопоставление один к одному, мы можем инвертировать внутренний словарь, чтобы получить сопоставление новых значений обратно оригиналу.
Теперь мы можем использовать уникальную возможность
replace
метода, чтобы взять вложенный список словарей и использовать внешние ключи в качестве столбцов, а внутренние ключи в качестве значений, которые мы хотели бы заменить.Мы можем легко вернуться к оригиналу, снова связав
replace
методисточник
После долгих поисков и экспериментов с некоторыми ответами здесь и в других местах, я думаю, что ваш ответ здесь :
Это сохранит имена категорий в столбцах:
источник
Я проверил исходный код ( https://github.com/scikit-learn/scikit-learn/blob/master/sklearn/preprocessing/label.py ) LabelEncoder. Он был основан на множестве преобразований numpy, одним из которых является np.unique (). И эта функция принимает только 1-й массив ввода. (поправьте меня, если я ошибаюсь).
Очень грубые идеи ... сначала определите, для каких столбцов нужен LabelEncoder, а затем переберите каждый столбец.
Возвращенный ДФ будет один после кодирования, и label_list покажет вам , что все эти значения означают в соответствующем столбце. Это фрагмент сценария обработки данных, который я написал для работы. Дайте мне знать, если вы думаете, что может быть дальнейшее улучшение.
РЕДАКТИРОВАТЬ: просто хочу упомянуть здесь, что методы выше работают с фреймом данных, не пропуская лучшее. Не уверен, как он работает, чтобы фрейм данных содержал недостающие данные. (Я имел дело с отсутствующей процедурой перед выполнением вышеуказанных методов)
источник
если у нас есть один столбец для кодирования меток и его обратного преобразования, то легко сделать это, когда в Python есть несколько столбцов
источник
Если у вас есть числовые и категориальные данные обоих типов в фрейме данных, вы можете использовать: здесь X - мой фрейм данных, имеющий категориальные и числовые обе переменные
Примечание: этот метод хорош, если вы не заинтересованы в преобразовании их обратно.
источник
Использование Neuraxle
С помощью этого метода ваш кодировщик этикеток сможет соответствовать и преобразовываться в обычный конвейер scikit-learn . Давайте просто импортируем:
Тот же общий кодер для столбцов:
Вот как один общий LabelEncoder будет применен ко всем данным для его кодирования:
Результат:
Различные кодеры на столбец:
И вот как первый автономный LabelEncoder будет применен к домашним животным, а второй будет разделен для владельца и местоположения столбцов. Чтобы быть точным, у нас здесь есть смесь различных и общих кодировщиков меток:
Результат:
источник
В основном использовал ответ @Alexander, но пришлось внести некоторые изменения -
Затем для повторного использования в будущем вы можете просто сохранить вывод в документ json, а когда вам это нужно, вы прочитаете его и используете
.map()
функцию, как я делал выше.источник
Проблема заключается в форме данных (pd dataframe), которые вы передаете в функцию подгонки. Вы должны пройти 1-й список.
источник
Здесь я читаю csv из местоположения, и в функции я передаю список столбцов, которые я хочу пометить, и фрейм данных, который я хочу применить.
источник
Как насчет этого?
Это не самый эффективный, однако он работает, и это очень просто.
источник