одноразовое кодирование на многомерных массивах с использованием pandas или scikit-learn

Я пытаюсь закодировать один горячий для своего фрейма данных. Это многомерный массив, и я не знаю, как это сделать. Фрейм данных может выглядеть так:

df = pd.DataFrame({'menu': [['Italian', 'Greek'], ['Japanese'], ['Italian','Greek', 'Japanese']], 'price': ['$$', '$$', '$'], 'location': [['NY', 'CA','MI'], 'CA', ['NY', 'CA','MA']]})

введите здесь описание изображения

Я хочу получить примерно такой результат:

df2 = pd.DataFrame({'menu': [[1,1,0], [0,0,1], [1,1,1]], 'price': [[1,0], [1,0], [0,1]], 'location': [[1,1,1,0], [0,1,0,0], [1,1,0,1]]})

введите здесь описание изображения

Я не уверен, как это можно сделать с помощью pd.get_dummies или scikit-learn. Кто-нибудь может мне помочь?


person 2D_    schedule 14.09.2017    source источник
comment
Работа со списками в фрейме данных - последнее, что вы хотите делать при использовании pandas. Это плохой дизайн - подумайте о том, чтобы отказаться от него.   -  person cs95    schedule 14.09.2017
comment
Вы можете ознакомиться с MultiLabelBinarizer и моим ответьте здесь о том, как его использовать. Но минус в том, что вам нужно обрабатывать каждый столбец, используя отдельный объект MultiLabelBinarizer. Также вам может потребоваться изменить элементы, не входящие в список, в столбце, чтобы они отображались как CA на [CA], потому что это то, что в нем требуется.   -  person Vivek Kumar    schedule 14.09.2017
comment
вы можете указать все возможные значения локаций?   -  person Espoir Murhabazi    schedule 14.09.2017
comment
@EspoirMurhabazi В данном случае я предполагаю, что все местоположения на данный момент следующие: Нью-Йорк, Калифорния, Мичиган, Массачусетс.   -  person 2D_    schedule 14.09.2017
comment
@ cᴏʟᴅsᴘᴇᴇᴅ Спасибо за отзыв. Не могли бы вы сказать мне, есть ли способ лучше взглянуть на эту проблему? Если pandas - плохой способ начать, у меня нет проблем с преобразованием моего набора данных в другой формат. Я просто не знаю, как лучше это сделать.   -  person 2D_    schedule 14.09.2017
comment
@ 2D_ Если вашей целью является машинное обучение, вам следует работать со списками и склеарном напрямую. Pandas используется для интеллектуального анализа данных и обработки чисел.   -  person cs95    schedule 14.09.2017
comment
@EspoirMurhabazi Спасибо за сообщение, я прочитал его, и он помог мне понять, как решить эту проблему.   -  person 2D_    schedule 15.09.2017
comment
2D_ скажи спасибо @jezrael, он тот, кто дал тебе ответ   -  person Espoir Murhabazi    schedule 15.09.2017


Ответы (1)


Вы можете использовать:

#create list with one item values
df = df.applymap(lambda x: x if isinstance(x, list) else [x])
print (df)
       location                        menu price
0  [NY, CA, MI]            [Italian, Greek]  [$$]
1          [CA]                  [Japanese]  [$$]
2  [NY, CA, MA]  [Italian, Greek, Japanese]   [$]

from sklearn.preprocessing import MultiLabelBinarizer

mlb = MultiLabelBinarizer()
#create Series for each column by list comprehension
vals = [pd.Series(mlb.fit_transform(df[x]).tolist()) for x in df.columns]
#concat to df
df2 = pd.concat(vals, keys=df.columns, axis=1)
print (df2)

       location       menu   price
0  [1, 0, 1, 1]  [1, 1, 0]  [0, 1]
1  [1, 0, 0, 0]  [0, 0, 1]  [0, 1]
2  [1, 1, 0, 1]  [1, 1, 1]  [1, 0]
person jezrael    schedule 14.09.2017
comment
Спасибо. Я воспользовался вашим предложением, и это сработало! У меня была ошибка TypeError: unorderable types: str () ›float (), и я думаю, что это вызвано моим значением nan. Я выясню, как поступить в этом случае. - person 2D_; 15.09.2017
comment
Да, тестирую - заменяю CA на np.nan. Итак, что вам нужно делать, если NaN? заменить NaN на строку типа missing? Или удалить все строки, где NaN? - person jezrael; 15.09.2017
comment
Для замены скаляров NaN на missinguse df = df.fillna('missing').applymap(lambda x: x if isinstance(x, list) else [x]) и для удаления всех строк с NaN используйте df = df.dropna().applymap(lambda x: x if isinstance(x, list) else [x]) - person jezrael; 15.09.2017
comment
Если NaNs в списке или в скалярах - df = df.fillna('missing').applymap(lambda x: [i if pd.notnull(i) else 'missing' for i in x] if isinstance(x, list) else [x]) - person jezrael; 15.09.2017