我挣扎了一段时间来改善这段代码的执行时间。由于计算非常耗时,我认为最好的解决方案是并行化代码。 输出也可以存储在内存中,然后写入文件。
我是Python和并行的新手,所以我发现很难应用here和here解释的概念。我还发现了this问题,但我无法弄清楚如何根据我的情况实现相同的问题。 我正在使用Python 3.4在Windows平台上工作。
for i in range(0, len(unique_words)):
max_similarity = 0
max_similarity_word = ""
for j in range(0, len(unique_words)):
if not i == j:
similarity = calculate_similarity(global_map[unique_words[i]], global_map[unique_words[j]])
if similarity > max_similarity:
max_similarity = similarity
max_similarity_word = unique_words[j]
file_co_occurring.write(
unique_words[i] + "\t" + max_similarity_word + "\t" + str(max_similarity) + "\n")
如果您需要代码说明:
unique_words
是一个单词列表(字符串)global_map
是一个词典,其键是单词(global_map.keys()
包含与unique_words
相同的元素),值是以下格式的词典:{word:value},其中单词是unique_words
global_map
中的值查找最相似的单词。我不愿意将每个相似性存储在内存中,因为地图已占用太多。calculate_similarity
返回0到1之间的值unique_words
中每个单词最相似的单词(最相似的单词应该与单词本身不同,这就是我添加条件if not i == j
的原因,但如果我检查max_similarity
是否不同于1)max_similarity
为0,如果最相似的单词是空字符串,则表示正常答案 0 :(得分:1)
这是一个适合您的解决方案。我最后更改了很多代码,所以请问你是否有任何问题。
这远不是实现这一目标的唯一方法,特别是这不是一种内存有效的解决方案。
您需要将max_workers设置为适合您的方式。通常,机器中逻辑处理器的数量是一个很好的起点。
from concurrent.futures import ThreadPoolExecutor, Future
from itertools import permutations
from collections import namedtuple, defaultdict
Result = namedtuple('Result', ('value', 'word'))
def new_calculate_similarity(word1, word2):
return Result(
calculate_similarity(global_map[word1], global_map[word2]),
word2)
with ThreadPoolExecutor(max_workers=4) as executer:
futures = defaultdict(list)
for word1, word2 in permutations(unique_words, r=2):
futures[word1].append(
executer.submit(new_calculate_similarity, word1, word2))
for word in futures:
# this will block until all calculations have completed for 'word'
results = map(Future.result, futures[word])
max_result = max(results, key=lambda r: r.value)
print(word, max_result.word, max_result.value,
sep='\t',
file=file_co_occurring)
以下是我使用的库的文档: