如何将数据框列的分类值转换为 sckikit-learn 中的单热编码列?

Posted

技术标签:

【中文标题】如何将数据框列的分类值转换为 sckikit-learn 中的单热编码列?【英文标题】:How to transform categorical values of a dataframe column to a one-hot encoded columns in sckikit-learn? 【发布时间】:2020-03-21 17:22:45 【问题描述】:

鉴于数据帧df 的分类值['A', 'B','C'] 的列letters,我想获得数据帧中的许多列,其中每一行只有一个与原始分类值对应的非零值。

例如来自数据框

letters
A
C
A
C

我想拥有:

A    B    C
1    0    0
0    0    1 
1    0    0
0    0    1

现在在 pandas 中这很容易:

dummies = pd.get_dummies(df.letters)
res = pd.concat([df, dummies], axis=1)
df.drop('letters', axis=1, inplace=True)

在 scikit 中可以使用LabelBinarizer

from sklearn.preprocessing import LabelBinarizer
cat_col = df["letters"]
encoder = LabelBinarizer()
col_1hot = encoder.fit_transform(cat_col)
col_1hot.toarray()

然而,这只是一个1-0 矩阵,我丢失了对原始分类值的引用。因此,我不能假设第一个 1-hot 列是 A,第二个是 B,依此类推。 那么如何在 SciKit learn 中执行 one-hot encoding 来获取数据帧呢?

编辑

@Joe Halliwell 建议做一些事情lb.inverse_transform(onehot) 所以在这个特定的情况下我做了

lb = preprocessing.LabelBinarizer()
onehot = lb.fit_transform(df)
res = pd.DataFrame(data=onehot, columns=lb.inverse_transform(onehot).reshape(-1,))

在这种情况下有效,因为行数等于类别。如果我有更多行,这将不再起作用

【问题讨论】:

【参考方案1】:

您不能使用 SciKit Learn 来获取 DataFrame。但是,您可以在已安装的 LabelBinarizer 上调用 inverse_transform 方法来检索标签,例如

import pandas as pd
from sklearn import preprocessing

df = pd.DataFrame("foo": ["A", "C", "B", "A"])
lb = preprocessing.LabelBinarizer()
onehot = lb.fit_transform(df)
print(lb.inverse_transform(onehot))

因此,为了检索 one-hot 编码矩阵中列的标签,您可以通过逆变换运行单位矩阵:

print(lb.inverse_transform(np.identity(onehot.shape[1]))

【讨论】:

lb.inverse_transform(encoder) 在行数等于类别数时可能很有用,但否则无济于事:请参阅我的问题的编辑 我添加了一条关于如何以正确顺序检索所有标签的注释。

以上是关于如何将数据框列的分类值转换为 sckikit-learn 中的单热编码列?的主要内容,如果未能解决你的问题,请参考以下文章

将数据框列转换为多行,重复其他列的值

Pandas:如何将数据框列中的“时间戳”值从对象/字符串转换为时间戳?

如何解压缩数据框列中存在的 json 的键,值将转换为键作为列,而使用 python 将其值转换为列?

如何迭代数据列的每个单元格,转换和附加每个单元格?

在Scala中转换所有数据框列的有效方法[重复]

如何截断火花数据框列的值? [复制]