首页 > 解决方案 > 如何更改此代码以使每个文件的进度条出现并且迭代是每个循环?

问题描述

我正在努力让tqdm' 的进度条保持和更新,而不是写入新行。注意:我multiprocessing用来并行化我的代码,并且tqdm在我正在并行化的函数内。

我添加了一条print语句,以便在运行程序时文件都将出现在我的终端中。下面的可重现示例:

import multiprocessing
import time

from tqdm import tqdm
from joblib import Parallel, delayed


def run_file_analysis(text):
    cool = []
    for i in tqdm(range(0, 10), position = 0, leave = True, desc = f'Text : {text}'):
        print('')
        cool.append(i)
        time.sleep(1)

num_cores = multiprocessing.cpu_count()
ls = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']

if __name__ == "__main__":
    processed_list = Parallel(n_jobs=num_cores)(delayed(run_file_analysis)(i) for i in ls)

电流输出: 在此处输入图像描述

所需的输出将是十个文本对象 - 1、2、3、...、10 和每个对应的更新进度条。不是100个不同的。我已经尝试关注许多与主题tqdmmultiprocessing集成相关的 stackoverflow 问题,但没有一个像我希望的那样简单。任何帮助,将不胜感激。

标签: pythonpython-3.xmultiprocessingtqdm

解决方案


正如评论中已经讨论的那样,您不想在 print 语句中添加额外的新行。相反,您想使用 tqdm 中的位置参数。文档中甚至提到了不同线程的用例。

position : int, optional
  Specify the line offset to print this bar (starting from 0)
  Automatic if unspecified. Useful to manage multiple bars at once (eg, from threads).

目前,此参数设置为 0,因此每次新建时都会启动进度条。相反,您想使用线程数。为简单起见,您可以将给定的文本转换为整数并使用它。但这不建议用于生产。

import multiprocessing
import time

from tqdm import tqdm
from joblib import Parallel, delayed


def run_file_analysis(text):
    cool = []
    for i in tqdm(range(0, 10), position=int(text), leave=True, desc = f'Text : {text}'):
        cool.append(i)
        time.sleep(1)

num_cores = multiprocessing.cpu_count()
ls = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']

if __name__ == "__main__":
    processed_list = Parallel(n_jobs=num_cores)(delayed(run_file_analysis)(i) for i in ls)

如果文本不能直接转换为整数,则可以使用“枚举”并将索引传递给函数。

import multiprocessing
import time

from tqdm import tqdm
from joblib import Parallel, delayed


def run_file_analysis(text, job_number):
    cool = []
    for i in tqdm(range(0, 10), position=job_number, leave=True, desc = f'Text : {text}'):
        cool.append(i)
        time.sleep(1)

num_cores = multiprocessing.cpu_count()
ls = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '10']

if __name__ == "__main__":
    processed_list = Parallel(n_jobs=num_cores)(delayed(run_file_analysis)(text, i) for i, text in enumerate(ls))

编辑:

prefer='threads'通过设置Parallel 构造函数可以减少一些竞争条件:

if __name__ == "__main__":
    processed_list = Parallel(n_jobs=num_cores, prefer="threads")(delayed(run_file_analysis)(text, i) for i, text in enumerate(ls))

推荐阅读