优化列表理解的并行实现

时间:2019-05-15 09:23:09

标签: python multithreading pandas

我有一个数据框,其中每一行都包含一个整数列表。我还有一个参考列表,用于检查数据帧中的哪些整数出现在此列表中。

我已经实现了两种实现,一种是单线程的,另一种是多线程的。单线程实现非常快(在我的计算机上大约需要0.1s),而多线程大约需要5s。

我的问题是:这是由于我的实现不佳,还是仅仅是由于多线程导致的开销如此之大以至于无法使用多个线程?

示例如下:

import time
from random import randint
import pandas as pd
import multiprocessing
from functools import partial

class A:
    def __init__(self, N):
        self.ls = [[randint(0, 99) for i in range(20)] for j in range(N)]
        self.ls = pd.DataFrame({'col': self.ls})

        self.lst_nums = [randint(0, 99) for i in range(999)]

    @classmethod
    def helper(cls, lst_nums, col):
        return any([s in lst_nums for s in col])

    def get_idx_method1(self):
        method1 = self.ls['col'].apply(lambda nums: any(x in self.lst_nums for x in nums))
        return method1

    def get_idx_method2(self):
        pool = multiprocessing.Pool(processes=1)
        method2 = pool.map(partial(A.helper, self.lst_nums), self.ls['col'])
        pool.close()
        return method2

if __name__ == "__main__":

    a = A(50000)

    start = time.time()
    m1 = a.get_idx_method1()
    end = time.time()
    print(end-start)

    start = time.time()
    m2 = a.get_idx_method2()
    end = time.time()
    print(end - start)

1 个答案:

答案 0 :(得分:0)

首先,当主进程与其他进程之间的数据通信成本与功能的时间成本可比性较低时,多处理很有用。

另一件事是您在代码中犯了一个错误:

def helper(cls, lst_nums, col):
    return any([s in lst_nums for s in col])

VS

any(x in self.lst_nums for x in nums)

您在helper方法中具有该列表[],它将使any()方法等待整个数组的计算,而第二个any()将仅在第一个True值处停止。

总而言之,如果您从辅助方法中删除列表括号,并可能增加lst_nums初始化程序的randint范围,则在使用多个进程时,您会发现速度有所提高。

self.lst_nums = [randint(0, 10000) for i in range(999)]

def helper(cls, lst_nums, col):
    return any(s in lst_nums for s in col)