【问题标题】:How to One Hot Encode in python for numerical?如何在 python 中对数字进行一次热编码?
【发布时间】: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。

【问题讨论】:

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


    【解决方案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
    • 嘿,我上次没有编辑输出...现在检查一下
    猜你喜欢
    • 2022-09-27
    • 2021-11-16
    • 2017-09-22
    • 2018-04-28
    • 2017-05-02
    • 2021-02-10
    • 2020-06-14
    • 1970-01-01
    相关资源
    最近更新 更多