for循环内的多处理

Posted

技术标签:

【中文标题】for循环内的多处理【英文标题】:multiprocessing inside a for loop 【发布时间】:2021-12-12 18:21:38 【问题描述】:

我已经阅读了多处理包和线程模块,但我不太确定如何在我的情况下使用它,尽管我仍然认为我可以从实现它中受益。

我目前正在编写一个处理和抓取一堆 html 文件的管道。我的清理方法遍历所有 HTML 文件并处理它们,方法是调用另一个提取数据并返回 pandas 数据框的方法。清理方法当前等待一个文件完成解析,这就是为什么我认为多处理在这里会有所帮助。

我不太确定线程或多处理是否是正确的选择,但我认为由于任务受 CPU 限制,多处理应该是完美的

这就是我的代码现在的样子:

def get_clean_df(self):
    # iterate through all existing html files and parse them
    for filepath in glob.glob("../data/source/*/*.html"):
    # expand existing dataframe with the newly parsed result
        result = pd.concat([result, self._extract_df_from_html(filepath)])

return result

感谢大家的帮助

【问题讨论】:

你能把你的函数_extract_df_from_html移到你的类实例之外吗? 很遗憾没有,因为我在另一个脚本中调用实例及其主要方法 所以答案是你不能,因为你的实例不能在多个进程之间共享。如果您的任务受 CPU 限制,即使您可以共享内存,使用线程也不是正确的选择。 还有什么替代方案 在类外创建一个辅助函数extract_df_from_html,返回清理后的数据框。 【参考方案1】:

根据我的 cmets,您可以创建如下内容:

import pandas as pd
import multiprocessing
import glob

def extract_df_from_html(filepath):
    # Do stuff here
    df = pd.DataFrame()
    return df

class Foo():
    def process(self):
        files = glob.glob("../data/source/*/*.html")
        with multiprocessing.Pool(4) as pool:
            result = pool.map(extract_df_from_html, files)
        self.result = pd.concat(result, ignore_index=True)

if __name__ == '__main__':
    foo = Foo()
    foo.process()

【讨论】:

能否在我的类中运行 main 函数中的代码? 试试看。我认为这不是问题。 我更新了我的答案。这也有效。 是的,我试过了,效果很好,只是有点弄乱了我的代码,但这有点不幸 多处理有点特殊。这是要付出的代价。如果这适合您的需要,请考虑接受我的回答和/或投票:)。我通过支持您的问题来补偿反对票。

以上是关于for循环内的多处理的主要内容,如果未能解决你的问题,请参考以下文章

以追加到列表为结果的多处理 for 循环

我将如何隔离或仅将第二个元素存储在批处理文件内的 for 循环中?

for循环内的回调函数-Nodejs

理解 vue-router的beforeEach无限循环的问题

Python 中的 for 循环中的多线程

for 循环内的 async.waterfall 转义 for 循环