如何在一个单元格中使用多个值进行一次热编码?

时间:2016-06-05 20:32:22

标签: python one-hot-encoding

我在Excel中有这个表:

id  class
0   2 3
1   1 3 
2   3 5

现在,我想在Python中进行'特殊'单热编码。 对于第一个表中的每个id,有两个数字。每个数字对应一个类(class1,class2等)。第二个表是基于第一个表创建的,对于每个id,其行中的每个数字都显示在其对应的类列中,而其他列只是得到零。例如,id 0的数字是2和3. 2位于class2,3位于class3。类1,4和5的默认值为0.结果应该是:

id  class1  class2  class3  class4  class5
 0   0       2        3       0       0
 1   1       0        3       0       0
 2   0       0        3       0       5

我之前的解决方案,

foo = lambda x: pd.Series([i for i in x.split()])
result=onehot['hotel'].apply(foo)
result.columns=['class1','class2']
pd.get_dummies(result, prefix='class', columns=['class1','class2'])

结果:

    class_1 class_2 class_3 class_3 class_5
  0  0.0     1.0    0.0      1.0    0.0
  1  1.0     0.0    0.0      1.0    0.0
  2  0.0     0.0    1.0      0.0    1.0

(class_3出现两次)。我该怎么做才能解决这个问题? (在此步骤之后,我可以将其转换为我想要的最终格式。)

3 个答案:

答案 0 :(得分:4)

您需要将变量设为categorical,然后才能使用one hot encoding,如下所示:

In [18]: df1 = pd.DataFrame({"class":pd.Series(['2','1','3']).astype('category',categories=['1','2','3','4','5'])})

In [19]: df2 = pd.DataFrame({"class":pd.Series(['3','3','5']).astype('category',categories=['1','2','3','4','5'])})

In [20]: df_1 = pd.get_dummies(df1)

In [21]: df_2 = pd.get_dummies(df2)

In [22]: df_1.add(df_2).apply(lambda x: x * [i for i in range(1,len(df_1.columns)+1)], axis = 1).astype(int).rename_axis('id')
Out[22]: 
    class_1  class_2  class_3  class_4  class_5
id                                             
0         0        2        3        0        0
1         1        0        3        0        0
2         0        0        3        0        5

答案 1 :(得分:3)

这是否满足您所述的问题?

on run
    tell application "Finder"
        set theItem to selection as string
    end tell
    set posixForm to POSIX path of theItem
    set the clipboard to posixForm
end run

输出:

#!/usr/bin/python

input = [
    (0, (2,3)),
    (1, (1,3)),
    (2, (3,5)),
]

maximum = max(reduce(lambda x, y: x+list(y[1]), input, []))
# Or ...
# maximum = 0
# for i, classes in input:
#    maximum = max(maximum, *classes)

# print header.
print "\t".join(["id"] + ["class_%d" % i for i in range(1, 6)])

for i, classes in input:
    print i,
    for r in range(1, maximum+1):
        print "\t",
        if r in classes:
            print float(r),
        else:
            print 0.0,
    print

答案 2 :(得分:3)

将原始数据框分成3列可能更简单:

id  class_a class_b
0   2          3
1   1          3  
2   3          5

然后对其执行正常的单热编码。之后,您可能会得到以下列的重复内容:

id  ... class_a_3 class_b_3 ... class_b_5
0          0          1             0
1          0          1             0
2          1          0             0

但你可以简单地合并/总结那些事实。

同样,您可以转动相同的逻辑并将您的df转换为以下形式:

id  class
0   2
0   3         
1   1
1   3         
2   3
2   5

然后炙手可热,并在密钥id上使用sum汇总。