python - 在 python 中并行化这个嵌套的 for 循环

标签 python parallel-processing multiprocessing python-multithreading python-multiprocessing

我又在努力改善这段代码的执行时间。由于计算非常耗时,我认为最好的解决方案是并行化代码。

我首先使用 map ,如 this 中所述问题,但后来我尝试了一种更简单的方法,认为我可以找到更好的解决方案。但是我还没有想出任何办法,所以由于这是一个不同的问题,我决定将它作为一个新问题发布。

我在 Windows 平台上工作,使用 Python 3.4。

代码如下:

similarity_matrix = [[0 for x in range(word_count)] for x in range(word_count)]
for i in range(0, word_count):
    for j in range(0, word_count):
        if i > j:
            similarity = calculate_similarity(t_matrix[i], t_matrix[j])
            similarity_matrix[i][j] = similarity
            similarity_matrix[j][i] = similarity

这是calculate_similarity 函数:

def calculate_similarity(array_word1, array_word2):
      denominator = sum([array_word1[i] + array_word2[i] for i in range(word_count)])
      if denominator == 0:
          return 0
      numerator = sum([2 * min(array_word1[i], array_word2[i]) for i in range(word_count)])
      return numerator / denominator

以及代码的解释:

  • word_count 是列表中存储的唯一单词的总数
  • t_matrix 是一个包含每对单词值的矩阵
  • 输出应该是 similarity_matrix 其维度是 word_count x word_count 也包含每对单词的相似度值
  • 可以将两个矩阵都保存在内存中
  • 在这些计算之后,我可以很容易地为每个词找到最相似的词(或者前三个相似词,根据任务的需要)
  • calculate_similarity 采用两个浮点列表,每个列表对应一个单独的单词(每个都是 t_matrix 中的一行)

我处理一个包含 13k 个单词的列表,如果我计算正确,我系统上的执行时间将是几天。所以,任何能在一天内完成工作的东西都会很棒!

也许仅在 calculate_similarity 中对 numeratordenominator 的计算进行并行化会带来显着的改进。

最佳答案

这是与 Matt's answer 中相同的通用算​​法的另一种实现方式,只是使用 multiprocessing.Pool 而不是 concurrent.futures.ProcessPoolExecutor。它可能比他的代码更有效,因为输入值 (t_matrix) 仅被序列化一次并传递给每个工作进程中的 initializer 函数。

import multiprocessing
import itertools

def worker_init(matrix):
    global worker_matrix
    worker_matrix = matrix

def worker(i, j):
    similarity = calculate_similarity(worker_matrix[i], worker_matrix[j])
    return i, j, similarity

def main(matrix):
    size = len(matrix)
    result = [[0]*size for _ in range(size)]
    with multiprocessing.Pool(initializer=worker_init, initargs=(matrix,)) as pool:
        for i, j, val in pool.starmap(worker, itertools.combinations(range(size), 2)):
            result[i][j] = result[j][i] = val
    return result

if __name__ == "__main__":
    # get t_matrix from somewhere
    main(t_matrix)

关于python - 在 python 中并行化这个嵌套的 for 循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29222986/

相关文章:

f# - 使用 Array.Parallel.map 减少运行时间

sql-server - SSRS 参数 - 来自查询的值(并行)

multithreading - 服务器上 CPU 密集型和 IO 密集型进程的多进程与多线程

python - 共享内存 值从对象中消失

python - Windows 多处理

python - 为什么 __del__ 在 with block 的末尾被调用?

python - Python 中的自定义协程

python - Pytest 标记 : mark entire directory/package

python - Tkinter 大型输入框

mpi - 执行并行代码的顺序部分(大量操作+写入文件)的有效方法?