【问题标题】:one-hot encoding on multi-dimension arrays, using pandas or scikit-learn使用 pandas 和 scikit-learn 对多维数组进行 one-hot 编码
【发布时间】:2018-02-23 01:42:01
【问题描述】:

我正在尝试为我的数据帧编码 one-hot。这是一个多维数组,我不知道该怎么做。数据框可能如下所示:

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 来完成。 有人能帮我吗?

【问题讨论】:

  • 处理数据框中的列表是使用 pandas 时最不想做的事情。这是一个糟糕的设计 - 考虑放弃它。
  • 你可以看看MultiLabelBinarizer和我的answer here如何使用它。但缺点是您必须使用单独的 MultiLabelBinarizer 对象处理每一列。此外,您可能需要将列中的非列表项更改为 CA[CA] 之类的列表,因为这就是其中所需要的。
  • 你能给出所有可能的位置值吗?
  • @EspoirMurhabazi 就本例而言,我假设所有地点现在都是:NY、CA、MI、MA。
  • @cᴏʟᴅsᴘᴇᴇᴅ 感谢您的反馈。你能告诉我是否有更好的方法来看待这个问题?如果 pandas 是一个不好的开始方式,那么将我的数据集转换为其他格式没有问题。我只是不知道哪种方法最好。

标签: python pandas scikit-learn vectorization one-hot-encoding


【解决方案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]

【讨论】:

  • 谢谢。我用了你的建议,它奏效了!我有错误“TypeError: unorderable types: str() > float()”,我认为这是由我的 nan 值引起的。我会想办法处理这种情况的。
  • 是的,我测试它 - 将 CA 替换为 np.nan。那么如果是 NaN,你需要做什么?将 NaN 替换为诸如missing 之类的字符串?或者删除所有包含 NaN 的行?
  • 将标量 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])
  • 如果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])
猜你喜欢
  • 2020-05-25
  • 2018-03-22
  • 2020-02-13
  • 2019-09-13
  • 2020-06-23
  • 1970-01-01
  • 2019-10-11
  • 2018-01-26
  • 1970-01-01
相关资源
最近更新 更多