2017-09-14 89 views
2

我正在尝试对我的数据帧进行一次热编码。这是一个多维数组,我不知道如何做到这一点。数据帧可以是这样的:使用熊猫或scikit-learn在多维数组上进行单向热编码

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

enter image description here

我想输出是这样的:

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]]}) 

enter image description here

我不知道如何可以做到这一点使用pd.get_dummies或scikit-learn。 有人可以帮我吗?

+1

在一个数据帧列表打交道是你想用大熊猫什么时候做的最后一件事。这是糟糕的设计 - 考虑放弃它。 –

+2

你可以看看[MultiLabelBinarizer](http://scikit-learn.org/stable/modules/generated/sklearn.preprocessing.MultiLabelBinarizer.html)和我的[answer here](https://stackoverflow.com/问题/ 42391165/how-to-one-hot-encode-variant-length-features/42392689#42392689)如何使用它。但是,你必须使用单独的MultiLabelBinarizer对象来处理每一列。你也可能需要将列中的非列表项改为列出,如'CA'到'[CA]',因为那是它所需要的。 –

+0

你能给出所有可能的位置值吗? –

回答

4

您可以使用:

#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] 
+0

谢谢。我用你的建议,它的工作!我有错误“ TypeError:无法订购的类型:str()> float()”,我认为这是由我的nan值引起的。我会弄清楚如何处理这种情况。 –

+1

是的,我测试它 - 取代CA到'np.nan'。那么,如果NaN你需要做什么?将NaN替换为“missing”之类的字符串?或者删除NaNs的所有行? – jezrael

+1

用于将标量NaNs替换为缺少使用df = df.fillna('missing')。applymap(lambda x:x if isinstance(x,list)else [x])'并且用于删除所有具有NaNs的行使用' df = df.dropna()。applymap(lambda x:x if isinstance(x,list)else [x])' – jezrael