我编写了一个脚本,它基本上将句子中的所有字符串分成几部分;
例如;
"geldigim" -> "gel" "di" "g" "i" "m"
虽然某些字符串可能会如上所述进行拆分,但其中一些字符串可能会按以下方式拆分;
"bildi" > "bil" "di"
或某些句子可能根本不会分开。
"kos" -> "kos"
完全由一个将字符串分成几部分的函数决定。
我想做的是以下内容:
geldigim -> /gel* *di* *g* *i* *m/
bildi -> /bil* *di/
kos -> /kos/
我做的是;
我有一个语料库,有37251512个句子。我写了以下脚本;
if __name__ == "__main__":
io = morfessor.MorfessorIO()
print "Importing corpus ..."
f = codecs.open("corpus/corpus_tr_en/corpus.tr", encoding="utf-8").readlines()
print "Importing morphology model ..."
model = io.read_binary_model_file('seg/tr/model.bin')
corpus = open('dataset/dataset_tr_en/full_segmented.tr', 'w')
for a in range(len(f)):
print str(a) + ' : ' + str(len(f))
words = f[a].replace('\n', '').split()
line_str = ''
for word in words:
segmentation = model.viterbi_segment(word)[0]
if len(segmentation) == 1:
line_str = '/' + segmentation[0] + '/'
if len(segmentation) == 2:
line_str = '/' + segmentation[0] + '* *' + segmentation[1] + '/'
if len(segmentation) > 2:
line_str = ''
for b in range(len(segmentation)):
if (b == 0):
line_str = line_str + '/' + segmentation[b] + '*'
if (b != 0) and (b != (len(segmentation) - 1)):
line_str = line_str + ' *' + segmentation[b] + '* '
if (b == (len(segmentation) - 1)):
line_str = line_str + ' *' + segmentation[b] + '/'
line_str = line_str + ' '
corpus.write(line_str.encode('utf-8'))
corpus.write('\n')
corpus.close()
这个脚本循环遍历每个句子和句子中的每个单词,并将其分成具有io.read_binary_model_file
函数的部分。
但它对我来说太贵了,它很慢。
你能否建议我一个让这个过程非常快的方法?
谢谢,
答案 0 :(得分:2)
使用多个字符串连接的line_str
的组合可能会减慢很多,如果你想要性能,则不建议这样做(对filename = base+".txt"
这样的事情是好的,但对于密集处理则不行。
创建line
作为list
,并使用str.join
创建最终字符串,以便将其写入磁盘。附加到list
要快得多。
正如马克西米利安刚刚建议的那样,你可以将你的条件变为elif
,因为它们彼此独占(x2)。还添加了一些可以提高可读性的微优化。
我建议你的内循环应该是这样的:
for word in words:
segmentation = model.viterbi_segment(word)[0]
lenseg = len(segmentation)
if lenseg == 1:
line = ['/',segmentation[0],'/']
elif lenseg == 2:
line = ['/',segmentation[0],'* *',segmentation[1],'/']
elif lenseg > 2:
line = []
for b in range(lenseg):
if b == 0:
line += ['/',segmentation[0],'*']
elif b != (lenseg - 1):
line += [' *',segmentation[b],'* ']
else:
line+= [' *',segmentation[b],'/']
line.append(" ")
corpus.write("".join(line).encode('utf-8'))
备选方案:
io.StringIO
对象并检索它以在输出文件中写入。答案 1 :(得分:2)
readlines()
用于37,251512个句子。只需使用for a in f
,请参阅here了解详细说明。 set
个单词代替重复单词全部重写可能会有所帮助。xrange
而不是range
.replace('\n', '').split()
很慢,因为当你只想删除最后一个换行符时,它必须遍历整行(在你的情况下不能有多个换行符)。你可以使用rstrip('\n')
`/
结尾,但你可以在3个地方结束。答案 2 :(得分:1)
这样的内循环怎么样:
line = '* *'.join(segmentation)
corpus.write(("/%s/ " % line).encode('utf-8'))
然后,既然你可以同时将输入保存在内存中,我也会尝试将输出保存在内存中,并一次性写出来,也许是这样:
lines = []
for a in range(len(f)):
print str(a) + ' : ' + str(len(f))
words = f[a].replace('\n', '').split()
for word in words:
line = '* *'.join(segmentation)
lines.append("/%s/ " % line)
corpus.write("\n".join(lines).encode('utf-8')