如何在 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 中对数字进行一次热编码?的主要内容,如果未能解决你的问题,请参考以下文章