【问题标题】:create one-hot encoding for multi-labels为多标签创建 one-hot 编码
【发布时间】:2021-12-13 17:29:25
【问题描述】:

鉴于以下数据存储在文本文件中:

fricative     f, s, S, x, v, z, Z, G, h
nasal       n, m, N
lateral   r, l, j, J
labial      p, b, m, f, v
coronal   s, z, n, d, t, r, l, j, J, S, Z
dorsal      g, k, G, x, N, h
frontal   e, i, I, E, E:, E~, j, J,  

如何创建一个单热编码函数,将单个字母放在第一列,并且在每个字母前面有一个描述现有标签的单热编码:

letters fricative nasal lateral labial coronal dorsal frontal
e 0 0 0 0 0 0 1
f 1 0 0 1 0 0 1
g 0 0 0 0 0 1 0
j 0 0 1 0 1 0 1

我查看了this link,但可以使用如下自定义函数:

def one_hot_labels(df):
    '''
    - for each line, create a dictionary indicating the presence (1) 
or the absence (0) of every label
    - put the dictionaries in the list and convert it to a data frame
    '''
dict_labels = []
for i in (range(len(df)), leave=False):
    d = dict(zip(range(n_labels), [0]*n_labels))
    ...
    dict_labels.append(d)

    df_labels = pd.DataFrame(dict_labels)
return df_labels

【问题讨论】:

  • 那么fricativef, s, S,... 是列名吗?
  • @QuangHoang 感谢您的回复。我刚刚修复了表格,列名是fricative nasal lateral labial coronal dorsal frontal 第一个列是字母,所以每行都是一个向量,如果列标题(即标签)存在则为 1,如果列标题(标签)不存在则为 0 .示例 row2 f 1 0 0 1 0 0 1 表示字母 f 是擦音、唇音和额音。

标签: python pandas dataframe one-hot-encoding


【解决方案1】:

试试.str.get_dummies():

# assuming the two columns are named `text` and `labels`
(df['letters'].str.replace(' ','')   # remove all spaces
    .str.get_dummies(',')            # get the dummies
    .set_index(df['text'])           # assign the associated text
    .T                               # transpose to match the requirement
)

这就是你得到的:

text  fricative  nasal  lateral  labial  coronal  dorsal  frontal
E             0      0        0       0        0       0        1
E:            0      0        0       0        0       0        1
E~            0      0        0       0        0       0        1
G             1      0        0       0        0       1        0
I             0      0        0       0        0       0        1
J             0      0        1       0        1       0        1
N             0      1        0       0        0       1        0
S             1      0        0       0        1       0        0
Z             1      0        0       0        1       0        0
b             0      0        0       1        0       0        0
d             0      0        0       0        1       0        0
e             0      0        0       0        0       0        1
f             1      0        0       1        0       0        0
g             0      0        0       0        0       1        0
h             1      0        0       0        0       1        0
i             0      0        0       0        0       0        1
j             0      0        1       0        1       0        1
k             0      0        0       0        0       1        0
l             0      0        1       0        1       0        0
m             0      1        0       1        0       0        0
n             0      1        0       0        1       0        0
p             0      0        0       1        0       0        0
r             0      0        1       0        1       0        0
s             1      0        0       0        1       0        0
t             0      0        0       0        1       0        0
v             1      0        0       1        0       0        0
x             1      0        0       0        0       1        0
z             1      0        0       0        1       0        0

【讨论】:

  • 感谢您的建议,但正如问题帖子中所述,get_dummies 似乎不起作用。例如字母f应该有一个像1 0 0 1 0 0 1这样的向量,但它给出1 0 0 1 0 0 0..这就是为什么我想使用一个带有for循环的自定义函数并构造字典再次感谢
  • 为什么frontal 里面会有f?你的数据没有吗?关于每个字母都应该提到一次,你在哪里看到重复的?
  • 你是对的。很抱歉这个错误。
【解决方案2】:

您可以将值读入setdict,然后使用所需条件构造DataFrame -

input_str = io.StringIO('''fricative     f, s, S, x, v, z, Z, G, h
nasal       n, m, N
lateral   r, l, j, J
labial      p, b, m, f, v
coronal   s, z, n, d, t, r, l, j, J, S, Z
dorsal      g, k, G, x, N, h
frontal   e, i, I, E, E:, E~, j, J''')

category_to_letters = dict()
letters = set()

for input in input_str:
    _category, *_letters = input.strip().split()
    _letters = set(_letter.split(',')[0] for _letter in _letters if _letter.split(',')[0].strip())
    category_to_letters[_category] = _letters
    letters = letters.union(set(_letters))

df = pd.DataFrame({}, index=letters, columns=category_to_letters.keys())
for col in df.columns:
    df.loc[:, col] = df.index.isin(category_to_letters[col])

【讨论】:

  • 谢谢。文本文件实际上要大得多,因此,最好使用函数def one_hot_encoding(fname): ... Return one_hot_encoding 从txt 中读取。
猜你喜欢
  • 1970-01-01
  • 2017-07-27
  • 2021-08-05
  • 2020-07-18
  • 2020-11-04
  • 2019-09-07
  • 2020-10-08
  • 1970-01-01
  • 2021-04-14
相关资源
最近更新 更多