生成独热编码的字符串表示

3 投票
4 回答
1597 浏览
提问于 2025-04-15 14:59

在Python中,我需要生成一个dict,这个字典的作用是把每个字母映射到一个预定义的“独热编码”表示。举个例子,这个dict应该长成这样:

{ 'A': '1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0',
  'B': '0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0', # ...
}

每个字母对应一个位(用字符表示)。所以每个字符串里会有25个零和一个1。这个1的位置是根据字母在字母表中的位置来决定的。

我写了一些代码来生成这个:

# Character set is explicitly specified for fine grained control
_letters = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
n = len(_letters)
one_hot = [' '.join(['0']*a + ['1'] + ['0']*b)
            for a, b in zip(range(n), range(n-1, -1, -1))]
outputs = dict(zip(_letters, one_hot))

有没有更高效、更简洁、更符合Python风格的方法来做到这一点呢?

4 个回答

1
one_hot = [' '.join(['0']*a + ['1'] + ['0']*b)
            for a, b in zip(range(n), range(n-1, -1, -1))]
outputs = dict(zip(_letters, one_hot))

特别是,这两行代码里包含了很多内容。你可以尝试使用引入解释变量这种重构方法。或者也可以试试提取方法

这里有一个例子:

def single_onehot(a, b):
    return ' '.join(['0']*a + ['1'] + ['0']*b)

range_zip = zip(range(n), range(n-1, -1, -1))
one_hot = [ single_onehot(a, b) for a, b in range_zip]
outputs = dict(zip(_letters, one_hot))

虽然你可能不同意我给它起的名字。

2

在Python 2.5及以上版本中,你可以使用条件运算符:

from string import ascii_uppercase

one_hot = {}
for i, c in enumerate(ascii_uppercase):
    one_hot[c] = ' '.join('1' if j == i else '0' for j in range(26))
7

我觉得这样更容易读懂:

from string import ascii_uppercase

one_hot = {}
for i, l in enumerate(ascii_uppercase):
    bits = ['0']*26; bits[i] = '1'
    one_hot[l] = ' '.join(bits)

如果你需要一个更通用的字母表,只需遍历一个包含字符的字符串,把 ['0']*26 替换成 ['0']*len(alphabet) 就可以了。

撰写回答