Pandas, python: How to one-hot-encode a column that contains an array of strings

Viewed 1294

I'm wondering how to one-hot-encode a column containing an array of strings.

I'm trying to get from df to df2:

import pandas as pd

# This is the original data frame
df = pd.DataFrame({'menu': [['Italian', 'Greek'], ['Japanese'],
                   ['Italian','Greek', 'Japanese']], 'price': ['$$', '$$', '$']})

df.head()

# This is the desired result

df2 = pd.DataFrame({'menu': [['Italian', 'Greek'], ['Japanese'], 
['Italian','Greek', 'Japanese']], 
                    'price': ['$$', '$$', '$'], 
                    'Italian': [1,0,1],
                    'Greek': [1,0,1],
                    'Japanese': [0,1,1]
                   })
df2.head()
2 Answers

Use MultiLabelBinarizer with join:

from sklearn.preprocessing import MultiLabelBinarizer

mlb = MultiLabelBinarizer()
df = df.join(pd.DataFrame(mlb.fit_transform(df['menu']),columns=mlb.classes_))
print (df)
                         menu price  Greek  Italian  Japanese
0            [Italian, Greek]    $$      1        1         0
1                  [Japanese]    $$      0        0         1
2  [Italian, Greek, Japanese]     $      1        1         1

You can use pd.get_dummies, pd.apply, DataFrame.join and Series.stack

df.join(pd.get_dummies(df.menu.apply(pd.Series).stack()).sum(level=0))

Output:

                         menu price  Greek  Italian  Japanese
0            [Italian, Greek]    $$      1        1         0
1                  [Japanese]    $$      0        0         1
2  [Italian, Greek, Japanese]     $      1        1         1
Related