2017-09-14 36 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