python多处理瓶颈

时间:2019-01-06 20:50:17

标签: python multiprocessing

我有一个python代码,最初使用sklearn lib训练一个KNN分类器,该分类器产生两个python对象:model和vectorizer。接下来将使用这两个对象对我的数据进行分类(分类)。

接下来,我有一个非常大的数据框,其中包含以下两列(在许多其他列中):

类别:此列将包含上面分类器的输出

data_path:此列是包含上面分类器输入的数据文件的路径

首先,我使用以下df.apply方法处理数据框:

def get_classifier_result(row, model, vectorizer):
    with open(row['data_path'], "r") as f:
        my_txt = f.readlines()
    ### run the classifier and classify my_txt input here and generate category value
    row['category'] = category

df = pd.read_csv(my_df, sep='\t', header=0)
df.apply(lambda row: get_classifier_result(row, model, vectorizer), axis=1) 

此代码花费了24小时才能在功能强大的56核Linux盒式服务器上运行。因此,我尝试使用多处理来加快速度:

import multiprocessing

def get_classifier_result(row, model, vectorizer):
    with open(row['data_path'], "r") as f:
        my_txt = f.readlines()
    ### run the classifier and classify my_txt input here and generate category value
    row['category'] = category

df = pd.read_csv(my_df, sep='\t', header=0)
p = multiprocessing.Pool(int(40))
for i, row in df.iterrows():
    p.apply_async(get_classifier_result, [row, model, vectorizer])

这种方法没有任何改善。在linux框上显示htop会显示所有40个进程都处于S(睡眠)模式,除了其中一个。因此,与df.apply方法一样,我实际上只运行一个进程。

问题似乎与模型和矢量化器对象的大小有关。如果我使用较小的训练数据集对分类器进行训练,以使模型和矢量化器对象的大小减小(比方说减小20倍),则htop将显示所有40个处于就绪模式且正在运行的进程,并且实际上会加速。我尝试使用Manager()并将共享列表中的这两个对象无济于事地传递给进程:

m = Manager()
my_list = [model,vectorizer]
my_shared_list = m.list(my_list)
for i, row in df.iterrows():
    p.apply_async(get_classifier_result, [row, my_shared_list])

我什至尝试在池中仅运行3个进程,但结果是相同的(只有一个进程处于活动状态,而另外两个处于睡眠模式)。

为什么只有一个进程以外的所有进程都处于睡眠模式并等待。一个人怎么知道他们还在等什么呢?为什么将参数对象的大小减小到生成过程中可以避免此问题?

0 个答案:

没有答案