并行化 python 中的嵌套 for 循环以查找最大值
Parallelize a nested for loop in python for finding the max value
我为改善这段代码的执行时间而苦苦挣扎了一段时间。由于计算非常耗时,我认为最好的解决方案是并行化代码。
输出也可以存储在内存中,然后写入文件。
我对 Python 和并行性都不熟悉,所以我发现很难应用解释的概念 here and here. I also found this 问题,但我无法弄清楚如何实现相同的我的情况。
我在 Windows 平台上工作,使用 Python 3.4.
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
returns 一个从 0 到 1 的值
- 结果应该包含
unique_words
中每个词最相似的词(最相似的词应该与词本身不同,这就是我添加条件 if not i == j
的原因,但是如果我检查 max_similarity
是否不同于 1) 也可以这样做
- 如果一个词的
max_similarity
为0,最相似的词是空串也可以
这是一个适合您的解决方案。我最终更改了您的很多代码,所以请询问您是否有任何问题。
这远不是实现此目的的唯一方法,尤其是这不是一种节省内存的解决方案。
您需要将 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)
以下是我使用的库的文档:
我为改善这段代码的执行时间而苦苦挣扎了一段时间。由于计算非常耗时,我认为最好的解决方案是并行化代码。 输出也可以存储在内存中,然后写入文件。
我对 Python 和并行性都不熟悉,所以我发现很难应用解释的概念 here and here. I also found this 问题,但我无法弄清楚如何实现相同的我的情况。 我在 Windows 平台上工作,使用 Python 3.4.
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
returns 一个从 0 到 1 的值- 结果应该包含
unique_words
中每个词最相似的词(最相似的词应该与词本身不同,这就是我添加条件if not i == j
的原因,但是如果我检查max_similarity
是否不同于 1) 也可以这样做
- 如果一个词的
max_similarity
为0,最相似的词是空串也可以
这是一个适合您的解决方案。我最终更改了您的很多代码,所以请询问您是否有任何问题。
这远不是实现此目的的唯一方法,尤其是这不是一种节省内存的解决方案。
您需要将 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)
以下是我使用的库的文档: