多标签二值化器输出的类别是字母而不是类别。

3
我有一个数据帧,其中一列是“short_names”。 “short_names”由名称的2-5个字母组成=>“BG”,“OP”,“LE”,“WEL”,“LC”。每行可以有任意数量的名称。
我正在尝试使用“MultiLabelBinarizer”将名称转换为单独的列,以便如果行具有相似的名称,则列中将有1。请注意保留HTML标记。
one_hot = MultiLabelBinarizer()
one_hot.fit_transform(df['short_name']) 
one_hot.classes__ 

由于其中一行中有一个'-',导致出现错误TypeError: 'float' object is not iterable,因此我已经使用了

df['short_names']= df['short_names'].astype(str)

现在的问题是,类的输出是字母而不是简称,例如ABC,而不是BGOP

print(df['short_name'].head().to_dict()) 是什么? - jezrael
{0: nan, 1: 'CE', 2: 'NPP', 4: 'SE, CB, CBN, OOM, BCI', 5: 'RCS'} - Lko
预期输出是什么?删除具有问题值的行吗? - jezrael
数组([[0, 0, 0, 0, 0,0,0,0], [0, 1, 0, 0, 0,0,0,0], [0, 0, 1, 1, 1,1,1,0], [0, 0, 0, 0, 0,0,01], 如果其他行中有相同的标签,则应指向同一列中的1 [1, 0, 0, 0, 1]]) - Lko
1个回答

3
我认为需要使用dropna来删除存在的缺失值,如果需要的话,可以使用split
df = pd.Series({0: np.nan, 1: 'CE', 2: 'NPP', 4: 'SE, CB, CBN, OOM, BCI', 5: 'RCS'})
       .to_frame('short_name')
print (df)
              short_name
0                    NaN
1                     CE
2                    NPP
4  SE, CB, CBN, OOM, BCI
5                    RCS

from sklearn.preprocessing import MultiLabelBinarizer
one_hot = MultiLabelBinarizer()
a = one_hot.fit_transform(df['short_name'].dropna().str.split(', ')) 
print (a)
[[0 0 0 1 0 0 0 0]
 [0 0 0 0 1 0 0 0]
 [1 1 1 0 0 1 0 1]
 [0 0 0 0 0 0 1 0]]

print(one_hot.classes_ )
['BCI' 'CB' 'CBN' 'CE' 'NPP' 'OOM' 'RCS' 'SE']

如果要输出DataFrame
df = pd.DataFrame(a, columns=one_hot.classes_ )
print (df)
   BCI  CB  CBN  CE  NPP  OOM  RCS  SE
0    0   0    0   1    0    0    0   0
1    0   0    0   0    1    0    0   0
2    1   1    1   0    0    1    0   1
3    0   0    0   0    0    0    1   0

另一个解决方案是使用fillna替换缺失值

from sklearn.preprocessing import MultiLabelBinarizer
one_hot = MultiLabelBinarizer()
a = one_hot.fit_transform(df['short_name'].fillna('missing').str.split(', ')) 
print (a)
[[0 0 0 0 0 0 0 0 1]
 [0 0 0 1 0 0 0 0 0]
 [0 0 0 0 1 0 0 0 0]
 [1 1 1 0 0 1 0 1 0]
 [0 0 0 0 0 0 1 0 0]]

print(one_hot.classes_ )
['BCI' 'CB' 'CBN' 'CE' 'NPP' 'OOM' 'RCS' 'SE' 'missing']

df = pd.DataFrame(a, columns=one_hot.classes_ )
print (df)
   BCI  CB  CBN  CE  NPP  OOM  RCS  SE  missing
0    0   0    0   0    0    0    0   0        1
1    0   0    0   1    0    0    0   0        0
2    0   0    0   0    1    0    0   0        0
3    1   1    1   0    0    1    0   1        0
4    0   0    0   0    0    0    1   0        0

它运行了!谢谢。错误的原因是什么? - Lko
为什么它输出字母而不是短名称? - Lko
如果我想要将列合并在一起,应该如何操作?假设我想要将CE和CBN中的"1"合并到一个新的列中。 - Lko
@Lko - 如果认为 a = one_hot.fit_transform(df['short_name'].astype(str)) 存在问题,需要使用列表而不是字符串。如果使用字符串,则每个值将被单独处理。 - jezrael
@jezrael 那我是应该只在**(训练集上拟合one_hot并仅转换测试集),还是在(训练集和测试集)上都进行拟合**呢? - 10sha25
@10sha25 - 我感到非常羞愧,但老实说我不知道 :( - jezrael

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接