生成独热编码的字符串表示
在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)
就可以了。