Estoy luchando con conseguir tqdm
's barra de progreso para quedarse y actualización en lugar de escritura a una nueva línea. Nota: Estoy usando multiprocessing
para paralelizar mi código, y tqdm
es dentro de la función que estoy paralelización.
He añadido una print
declaración por lo que los archivos serán todos aparecen en mi terminal cuando se ejecuta el programa. Ejemplo reproducible a continuación:
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)
The desired output would be the ten text objects - 1, 2, 3, ... , 10 and a corresponding updating progress bar for each. Not 100 different ones. I have tried following many stackoverflow questions relating to the topic of tqdm
and multiprocessing
integration, but none of them are as straightforward as I would like them to be. Any help would be appreciated.
As already discussed in the comments, you don't want to add an extra new line with the print statement. Instead you want to use the position argument in tqdm. The use case for different threads is even mentioned in the docs.
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).
Actualmente, este argumento se establece en 0, por lo que se iniciará la barra de progreso cada vez nueva. En lugar de ello desea utilizar el número de la rosca. Debido a la simplicidad, puede convertir el texto dado a un entero y usar esto. Pero esto no es recomendable para la producción.
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)
Si los de texto no pueden convertirse directamente en número entero, 'enumerate' se puede utilizar un índice se puede pasar a la función.
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))
Editar:
Algunos raceconditions se pueden reducir mediante el establecimiento prefer='threads'
al constructor paralelo:
if __name__ == "__main__":
processed_list = Parallel(n_jobs=num_cores, prefer="threads")(delayed(run_file_analysis)(text, i) for i, text in enumerate(ls))