对于NLP任务,给定映射,我需要将每个unicode字符编码为单词列表列表中的整数。我试图找到一种快速的方法来做到这一点,而不是直接进入cython。
这是编写函数的一种缓慢的方法:
def encode(sentences, mappings):
encoded_sentences = []
for sentence in sentences:
encoded_sentence = []
for word in sentence:
encoded_word = []
for ch in word:
encoded_word.append(mappings[ch])
encoded_sentence.append(encoded_word)
encoded_sentences.append(encoded_sentence)
return encoded_sentences
给出以下输入数据:
my_sentences = [['i', 'need', 'to'],
['tend', 'to', 'tin']]
mappings = {'i': 0, 'n': 1, 'e': 2, 'd':3, 't':4, 'o':5}
我希望encode(my_sentences, mappings)
生成:
[[[0], [1, 2, 2, 3], [4, 5]],
[[4, 2, 1, 3], [4, 5], [4, 0, 1]]]
答案 0 :(得分:3)
列表理解快23%(更简洁):
%%timeit
encode(my_sentences, mappings)
100000 loops, best of 3: 4.75 µs per loop
def encode_compr(sentences, mappings):
return [[[mappings[char] for char in word] for word in sent] for sent in sentences]
%%timeit
encode_compr(my_sentences, mappings)
100000 loops, best of 3: 3.67 µs per loop
string.translate
import string
_from = 'inedto'
_to = '012345'
trans = string.maketrans(_from, _to)
def encode_translate(sentences, mappings):
return [[[int(string.translate(char, trans)) for char in word] for word in sent] for sent in sentences]
%%timeit
encode_translate(my_sentences, mappings)
100000 loops, best of 3: 17.4 µs per loop
答案 1 :(得分:3)
如果您将其用于批量转换,则可以从str.translate
(Py2)或bytes.translate
(Py3)获得一些内容,避免使用重量级的单个int
值,而是执行C级转换。最终结果不是list
的{{1}},而是list
list
(或Py3上的bytearray
);对于小bytes
个值的集合(从0到255)int
在很大程度上是等价的(它是一个可变序列,就像bytearray
)所以它通常都是你需要的。首先,在函数外部,您可以创建一个转换表:
list
然后在函数中使用它:
# Py2
import string
transtable = string.maketrans('inedto', str(bytearray(range(6))))
# Py3
transtable = bytes.maketrans(b'inedto', bytes(range(6)))
Py2上的计时在原始时间内达到约2/3的结果:
# Py2
def encode(sentences, mappings):
return [[bytearray(w).translate(mappings) for w in sentence]
for sentence in sentences]
# Py3
def encode(sentences, mappings):
# Assumes sentences are bytes, not str; can be tweaked to work with str
# but it will be slower/more complicated
return [[w.translate(mappings) for w in sentence]
for sentence in sentences]
Py3改进类似,但前提是输入句子是>>> %timeit -r5 encode(my_sentences, mapping) # Original function
100000 loops, best of 5: 4.51 µs per loop
>>> %timeit -r5 encode(my_sentences, transtable) # My alternate function
100000 loops, best of 5: 2.97 µs per loop
个对象,而不是bytes
(因此避免额外的转换)。这完全取决于您在输入和输出格式上可以使用的内容。