Python 函数内部的并行性?

Python 函数内部的并行性?,python,multithreading,list,parallel-processing,Python,Multithreading,List,Parallel Processing,我有一个计算项目列表在以下行中出现频率的函数: def count(pair_list): return float(sum([1 for row in rows if all(item in row.split() for item in pair_list)])) if __name__ == "__main__": pairs = [['apple', 'banana'], ['cookie', 'popsicle'], ['candy', 'cookie'], ...]

我有一个计算项目列表在以下
行中出现频率的函数:

def count(pair_list):
    return float(sum([1 for row in rows if all(item in row.split() for item in pair_list)]))

if __name__ == "__main__":
    pairs = [['apple', 'banana'], ['cookie', 'popsicle'], ['candy', 'cookie'], ...]
    # grocery transaction data
    rows = ['apple cookie banana popsicle wafer', 'almond milk eggs butter bread', 'bread almonds apple', 'cookie candy popsicle pop', ...]

    res = [count(pair) for pair in pairs]
实际上,
len(rows)
10000
,并且
对中有
18000
个元素,因此
count()
中的列表理解和主函数中的列表理解的计算成本很高

我尝试了一些并行处理:

from multiprocessing.dummy import Pool as ThreadPool
import multiprocessing as mp

threadpool = ThreadPool(processes = mp.cpu_count())

res = threadpool.map(count, pairs)
这也不是很快。事实上,15分钟后,我辞掉了这份工作,因为它看起来并没有结束。两个问题:1)如何加快在
count()
中进行的实际搜索?2) 我如何检查
threadpool.map
进程的状态(即查看还有多少对需要迭代)?

1)计算的总体复杂性是巨大的,它来自不同的来源:

a) 您在较低的计算级别上拆分行,所以python必须为每个迭代创建新的行拆分。为了避免这种情况,可以预先计算行。类似这样的操作将完成此工作(对“计数”功能进行轻微更改):

b) 您可以逐个比较列表项,即使只需要检查另一个列表中是否存在单词。在这里,我们可以进一步调整它(并在“count”函数中使用rows3而不是rows2):

c) 你把每一个单词成对地检查,每一个单词排成一行。对于原始版本,每次调用“count”函数时,计算需要2*len(行)*len(行)次迭代,而计算所需的时间更少。对于选项b),在良好的情况下,它可以降到2*len(行),但可以对每对进行一次设置查找,而不是2次。 诀窍是为每一行准备所有可能的单词*单词组合,并检查该集中是否存在对应的元组。 因此,在main函数中创建复杂的不可变搜索结构:

rows4 = [set((a, b) for a in row for b in row) for row in rows2]
现在“计数”看起来不同了,它采用元组而不是列表:

def count2(pair):
    return float(len([1 for row in rows4 if(pair in row)]))
所以你称之为有点不同: res=[count2(元组(对))表示成对成对]

请注意,创建搜索结构在时间和空间上每行需要len(row.split())^2,因此如果您的行可能很长,则这不是最佳选择。毕竟,选项b)可能更好


2) 您可以预测“count”的调用数,即len(pairs)。计数“Count”函数的调用,并在其中进行调试打印,例如,每1000次调用

它正忙于共享大的
。尝试将chunksize=100传递给
map
。关于您的问题,请使用imap。不过,我认为真正的问题必须是
count()
中的列表理解。这难道不是瓶颈吗,这里,与仅仅迭代
对中的所有p来获得
计数(p)
相比,我应该在哪里运行这个脚本?我应该在Windows系统中通过
cmd
运行它吗?或者可能是因为我在空闲状态下运行,所以速度很慢?很有帮助。整个剧本现在都飞起来了!
rows4 = [set((a, b) for a in row for b in row) for row in rows2]
def count2(pair):
    return float(len([1 for row in rows4 if(pair in row)]))