web-dev-qa-db-ja.com

マルチプロセッシング:tqdmを使用してプログレスバーを表示する

コードをより「Python的に」高速にするために、「マルチプロセッシング」とマップ関数を使用して、a)関数とb)反復範囲を送信します。

埋め込まれたソリューション(つまり、tqdm.tqdm(range(0、30)の範囲でtqdmを直接呼び出す)は、マルチプロセッシングでは機能しません(以下のコードで定式化されています)。

進行状況バーは0から100%まで表示されます(pythonがコードを読み取るとき?)が、マップ関数の実際の進行状況を示していません。

「マップ」機能がどのステップにあるかを示すプログレスバーを表示する方法

from multiprocessing import Pool
import tqdm
import time

def _foo(my_number):
   square = my_number * my_number
   time.sleep(1)
   return square 

if __== '__main__':
   p = Pool(2)
   r = p.map(_foo, tqdm.tqdm(range(0, 30)))
   p.close()
   p.join()

ヘルプや提案は大歓迎です...

59
SciPy

ソリューションが見つかりました:注意してください!マルチプロセッシングのため、推定時間(ループごとの反復、合計時間など)は不安定になる可能性がありますが、進行状況バーは完全に機能します。

注:プールのコンテキストマネージャーは、Pythonバージョン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 __== '__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()
36
SciPy

処理された値の反復子を返すmapの代わりにimapを使用します。

from multiprocessing import Pool
import tqdm
import time

def _foo(my_number):
   square = my_number * my_number
   time.sleep(1)
   return square 

if __== '__main__':
   with Pool(2) as p:
      r = list(tqdm.tqdm(p.imap(_foo, range(30)), total=30))
76
hkyi

xaviMartínezの答えに基づいて、関数imap_unordered_barを作成しました。 imap_unorderedと同じ方法で使用できますが、処理バーが表示される点が異なります。

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 __== '__main__':
    result = imap_unordered_bar(_foo, range(5))
6
Oliver Wilken

代わりにp_tqdmを使用できます。

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 __== '__main__':
   r = p_map(_foo, list(range(0, 30)))
2
Victor Quach

このアプローチは簡単で、機能します。

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()
0
Vijayabhaskar J