Multiprocesamiento: use tqdm para mostrar una barra de progreso

Para hacer que mi código sea más “pythonic” y más rápido, uso “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 de 0 a 100% (cuando Python lee el código?), Pero no indica el progreso real de la función del mapa.

¿Cómo mostrar una barra de progreso que indique 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 son bienvenidas …

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)) 

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

Nota: Context Manager para 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() 

imap_unordered_bar 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)) 

Puedes 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)))