これは、tqdm_notebookが機能しない場合の代替回答です。
次の例の場合:
from time import sleep
from tqdm import tqdm
values = range(3)
with tqdm(total=len(values)) as pbar:
for i in values:
pbar.write('processed: %d' %i)
pbar.update(1)
sleep(1)
出力は次のようになります(進行状況は赤で表示されます)。
0%| | 0/3 [00:00<?, ?it/s]
processed: 1
67%|██████▋ | 2/3 [00:01<00:00, 1.99it/s]
processed: 2
100%|██████████| 3/3 [00:02<00:00, 1.53it/s]
processed: 3
問題は、stdoutとstderrへの出力が、新しい行に関して非同期で個別に処理されることです。
たとえば、Jupyterがstderrで最初の行を受信し、次に「処理された」出力をstdoutで受信したとします。次に、stderrで出力を受け取って進行状況を更新すると、最後の行しか更新されないため、最初の行に戻って更新することはありません。代わりに、新しい行を記述する必要があります。
回避策1、stdoutへの書き込み
回避策の1つは、代わりに両方をstdoutに出力することです。
import sys
from time import sleep
from tqdm import tqdm
values = range(3)
with tqdm(total=len(values), file=sys.stdout) as pbar:
for i in values:
pbar.write('processed: %d' % (1 + i))
pbar.update(1)
sleep(1)
出力は次のように変わります(赤ではなくなります):
processed: 1 | 0/3 [00:00<?, ?it/s]
processed: 2 | 0/3 [00:00<?, ?it/s]
processed: 3 | 2/3 [00:01<00:00, 1.99it/s]
100%|██████████| 3/3 [00:02<00:00, 1.53it/s]
ここでは、Jupyterが行の終わりまでクリアされないように見えることがわかります。スペースを追加することで、別の回避策を追加できます。といった:
import sys
from time import sleep
from tqdm import tqdm
values = range(3)
with tqdm(total=len(values), file=sys.stdout) as pbar:
for i in values:
pbar.write('processed: %d%s' % (1 + i, ' ' * 50))
pbar.update(1)
sleep(1)
それは私たちに与えます:
processed: 1
processed: 2
processed: 3
100%|██████████| 3/3 [00:02<00:00, 1.53it/s]
回避策2、代わりに説明を設定
一般に、2つの出力を持たず、代わりに説明を更新する方が簡単かもしれません。例:
import sys
from time import sleep
from tqdm import tqdm
values = range(3)
with tqdm(total=len(values), file=sys.stdout) as pbar:
for i in values:
pbar.set_description('processed: %d' % (1 + i))
pbar.update(1)
sleep(1)
出力を使用して(処理中に説明が更新されます):
processed: 3: 100%|██████████| 3/3 [00:02<00:00, 1.53it/s]
結論
ほとんどの場合、プレーンなtqdmで問題なく動作します。ただし、tqdm_notebookが機能する場合は、それを使用してください(ただし、おそらくそれまではここを読みません)。
tqdm_notebook
、通常print
のを実行することもでき、進行状況バーには影響しません。