如何使用 get_dummies 或一种热编码对具有多个元素的分类特征进行编码?

时间:2021-04-16 03:43:38

标签: python pandas encoding one-hot-encoding

我正在处理一个数据集,它有一个名为类别的功能。该特征中每个观察的数据由分号分隔的列表组成,例如。

<头>
类别
第 1 行 "categorya;categoryb;categoryc"
第 2 行 "categorya;categoryb"
第 3 行 "categoryc"
第 4 行 "categoryb;categoryc"

如果我尝试pd.get_dummies(df,columns=['categories'])

我取回包含完整数据的列作为名为的列,例如名为 categorya;categoryb;categoryc 的列

如果我尝试

pd.get_dummies(df.categories.str.split(";").apply(pd.Series).stack(),columns=['categories'])

我得到了单独的列名,例如类别a,类别b。

但我只会在一列中得到 1,例如如果原始类别值是“categoryb;categoryc”,我只会在 b 中得到 1 而不是 c 值。

我觉得除了编码问题之外,我的方法可能犯了根本性错误?

1 个答案:

答案 0 :(得分:2)

在我看来,您正在更改数据结构的形状,使其与 DF 不匹配。

df.categories.str.split(";").apply(pd.Series).stack()

0  0    categorya
   1    categoryb
   2    categoryc
1  0    categorya
   1    categoryb
2  0    categoryc
3  0    categoryb
   1    categoryc

pd.get_dummies(df.categories.str.split(";").apply(pd.Series).stack())

     categorya  categoryb  categoryc
0 0          1          0          0
  1          0          1          0
  2          0          0          1
1 0          1          0          0
  1          0          1          0
2 0          0          0          1
3 0          0          1          0
  1          0          0          1

如果您事先知道类别,您可以执行以下操作:

df['categorya'] = np.where(df['categories'].str.contains('categorya'),1,0)

                      categories  categorya
0  categorya;categoryb;categoryc          1
1            categorya;categoryb          1
2                      categoryc          0
3            categoryb;categoryc          0

或者,如果您事先不知道类别,您可以这样做:

for s in df.categories.str.split(";").apply(pd.Series).stack().unique():
    df[s] = np.where(df['categories'].str.contains(s),1,0)

   categorya  categoryb  categoryc
0          1          1          1
1          1          1          0
2          0          0          1
3          0          1          1

此外,您可以按主要索引和分类(虚拟)列的总和进行聚合,以获得您要查找的内容。

Grouped get_dummies

像这样:

pd.get_dummies(df.categories.str.split(";").apply(pd.Series).stack()) \
    .groupby(level=0).sum()

   categorya  categoryb  categoryc
0          1          1          1
1          1          1          0
2          0          0          1
3          0          1          1

然后是最简单的:

df['categories'].str.get_dummies(sep=';')

       categories  catA  catB  catC
0  catA;catB;catC     1     1     1
1       catA;catB     1     1     0
2            catC     0     0     1
3       catB;catC     0     1     1