notebook bar python multiprocessing progress-bar tqdm

bar - tqdm notebook python



Multiprocesamiento: use tqdm para mostrar una barra de progreso (5)

Para hacer mi código más "pitónico" y más rápido, utilizo "multiprocesamiento" y una función de mapa para enviarlo a) la función yb) el rango de iteraciones.

La solución implantada (es decir, llamar a tqdm directamente en el rango tqdm.tqdm (rango (0, 30)) no funciona con multiprocesamiento (como se formula en el código a continuación).

La barra de progreso se muestra del 0 al 100% (cuando Python lee el código?) Pero no indica el progreso real de la función de mapa.

¿Cómo mostrar una barra de progreso que indica en qué paso se encuentra la función ''mapa''?

from multiprocessing import Pool import tqdm import time def _foo(my_number): square = my_number * my_number time.sleep(1) return square if __name__ == ''__main__'': p = Pool(2) r = p.map(_foo, tqdm.tqdm(range(0, 30))) p.close() p.join()

Cualquier ayuda o sugerencia es bienvenida ...


Este enfoque es simple y funciona.

from multiprocessing.pool import ThreadPool import time from tqdm import tqdm def job(): time.sleep(1) pbar.update() pool = ThreadPool(5) with tqdm(total=100) as pbar: for i in range(100): pool.apply_async(job) pool.close() pool.join()


Puede usar p_tqdm en p_tqdm lugar.

https://github.com/swansonk14/p_tqdm

from p_tqdm import p_map import time def _foo(my_number): square = my_number * my_number time.sleep(1) return square if __name__ == ''__main__'': r = p_map(_foo, list(range(0, 30)))


Solución encontrada: ¡Cuidado! Debido al multiprocesamiento, el tiempo de estimación (iteración por ciclo, tiempo total, etc.) podría ser inestable, pero la barra de progreso funciona perfectamente.

Nota: Context Manager for Pool solo está disponible desde Python versión 3.3

from multiprocessing import Pool import time from tqdm import * def _foo(my_number): square = my_number * my_number time.sleep(1) return square if __name__ == ''__main__'': with Pool(processes=2) as p: max_ = 30 with tqdm(total=max_) as pbar: for i, _ in tqdm(enumerate(p.imap_unordered(_foo, range(0, max_)))): pbar.update()


Use imap en lugar de map, que devuelve un iterador de valores procesados.

from multiprocessing import Pool import tqdm import time def _foo(my_number): square = my_number * my_number time.sleep(1) return square if __name__ == ''__main__'': with Pool(2) as p: r = list(tqdm.tqdm(p.imap(_foo, range(30)), total=30))


basado en la respuesta de Xavi Martínez escribí la función imap_unordered_bar . Se puede usar de la misma manera que imap_unordered con la única diferencia de que se muestra una barra de procesamiento.

from multiprocessing import Pool import time from tqdm import * def imap_unordered_bar(func, args, n_processes = 2): p = Pool(n_processes) res_list = [] with tqdm(total = len(args)) as pbar: for i, res in tqdm(enumerate(p.imap_unordered(func, args))): pbar.update() res_list.append(res) pbar.close() p.close() p.join() return res_list def _foo(my_number): square = my_number * my_number time.sleep(1) return square if __name__ == ''__main__'': result = imap_unordered_bar(_foo, range(5))