如何在 python 中对数字进行一次热编码?

Posted

技术标签:

【中文标题】如何在 python 中对数字进行一次热编码?【英文标题】:How to One Hot Encode in python for numerical? 【发布时间】:2020-11-14 13:32:55 【问题描述】:

我是 python 新手,想了解如何使用 scikitlearn

我有一个数据框:

         Id        ServiceSubCodeKey  ...         Aim   PrintDate
0        1895650                  2  ...          NaN  2018-07-27
1        1895650                  4  ...          NaN  2018-08-13
2        1896355                  2  ...          NaN  2018-08-10
3        1897675                  9  ...         12.0  2018-08-13
4        1897843                  2  ...          NaN  2018-08-10
         ...                ...  ...          ...         ...
3940510  2178737                 3  ...          1.0  2019-06-14
3940511  2178737                 4  ...          1.0  2019-06-14
3940512  2178737                 7  ...          1.0  2019-06-14
3940513  2178737                 1  ...          1.0  2019-06-14
3940514  2178750                 6  ...          4.0  2019-06-14

我正在尝试根据 id 与 servicesubcodekey 对 300 万行进行热编码,以便最终的 One 热编码如下所示:

           id   ServiceSubCodeKey  ...           Encoding   PrintDate
0        1895650                  2  ...          0101          2018-07-27
1        1895650                  4  ...          0101          2018-08-13
2        1896355                  2  ...          01          2018-08-10
3        1897675                  9  ...          000000001   2018-08-13
4        1897843                  2  ...          01          2018-08-10
         ...                ...  ...          ...         ...
3940510  2178737                 3  ...          1011001         2019-06-14
3940511  2178737                 4  ...          1011001         2019-06-14
3940512  2178737                 7  ...          1011001     2019-06-14
3940513  2178737                 1  ...          1011001     2019-06-14
3940514  2178750                 6  ...           000001      2019-06-14

因此,正如您所看到的,对于每个具有服务子代码的 id,都有一个唯一的编码,如果 id 相同,则编码是服务子代码的范围,并且对于数字,例如 id 18,如果最大服务子代码为 4,然后编码为 0101,因为该 id 存在 2 和 4。

【问题讨论】:

【参考方案1】:

我想我能够为此生成一种方法:

import pandas as pd
from operator import add
df = pd.DataFrame([
[1895650,2,float("nan"),  "2018-07-27"],
[1895650,4,float("nan"),  "2018-08-13"],
[1896355,2,float("nan"),  "2018-08-10"],
[1897675,9,12.0 ,"2018-08-13"],
[1897843,2,float("nan"),"2018-08-10"],
[2178737,3,1.0,  "2019-06-14"],
[2178737,4,1.0, "2019-06-14"],
[2178737,7,1.0 , "2019-06-14"],
[2178737,1,1.0 , "2019-06-14"],
[2178750,6,4.0 , "2019-06-14"]],columns = ["Id","ServiceSubCodeKey","Aim","PrintDate"])

首先我们对分类变量进行一次热编码并将它们放在一起:

columns = pd.get_dummies(df["ServiceSubCodeKey"]).astype(str)
df2 = columns[1]
for col in columns.columns[1::]:
    df2 += columns[col]

然后我们将它们添加到我们的原始数据集中:

df3 = pd.concat([df, df2], axis=1)
df3[1] = df3[1].apply(lambda x: list(map(int, list(x))))

我们将列表组合在一起并求和:

df4 = df3[["Id",1]].groupby("Id").agg(lambda x: sum_l(x)).reset_index()
df4[1] = df4[1].apply(lambda x: sum_l2(x))
df4[1] = df4[1].apply(lambda x: f(x))
df4[1] = df4[1].apply(lambda x: ''.join(list(map(str, list(x)))))

最后加入他们:

df5 = pd.merge(df,df4, on="Id", how="left")
df5

    Id      ServiceSubCodeKey   Aim     PrintDate   1
0   1895650 2                   NaN     2018-07-27  0101
1   1895650 4                   NaN     2018-08-13  0101
2   1896355 2                   NaN     2018-08-10  01
3   1897675 9                   12.0    2018-08-13  0000001
4   1897843 2                   NaN     2018-08-10  01
5   2178737 3                   1.0     2019-06-14  101101
6   2178737 4                   1.0     2019-06-14  101101
7   2178737 7                   1.0     2019-06-14  101101
8   2178737 1                   1.0     2019-06-14  101101
9   2178750 6                   4.0     2019-06-14  00001

我们还需要以下函数:

def sum_l(values):
    out = []
    for element in values:
        out.append(element)
    return out

def sum_l2(values):
    
    if type(values[0]) != int:
        out = values[0]
        for i in range(1,len(values)):
            out = list(map(add, out, values[i]))
    else:
        out = values
    return out

def f(x):
    while x[-1] == 0:
        x.pop()
    return x

【讨论】:

嗨,我在 onehot 代码分类变量步骤 vals1d = values.ravel() MemoryError 后收到内存错误。由于我在我的 df 中处理 300 万行,有没有办法错误处理这个? 你能编辑你的问题并详细解释错误吗?似乎您在 ServiceSubCodeKey 中有太多值,或者您需要分片处理数据集,然后加入它们,而不是一次加入所有内容。 可以,但在这个较小的样本上,您的解决方案有效。但只有一个主要问题是,为什么它在 id 1895650 之后显示 0101000 三个零?最大 subcodekey 是 4。它应该是 0101,之后不再有零。你有解决办法吗?我会把它标记为正确的@让我们试试 它仍然为 id 189560 提供相同的输出 0101000。它应该只显示 0101。另外,请注意最后一个 ID 2178750,其中 ssc 为 6,编码错误地放置在 0000100。它应该只是 000001 嘿,我上次没有编辑输出...现在检查一下

以上是关于如何在 python 中对数字进行一次热编码?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 R 中对多个分类变量进行一次热编码

如何在使用 sklearn 进行一次热编码后给出列名?

如何在使用 sklearn 进行一次热编码后给出列名?

Julia DataFrames - 如何进行一次热编码?

如何使用 sklearn 对 CSV 文件中的多列进行一次热编码?

一次对多列进行一次热编码并附加到主数据集?