Jupyterノートブックで実行しているスクリプトの進行状況を印刷するためにtqdm
を使用しています。私はすべてのメッセージをtqdm.write()
経由でコンソールに表示しています。しかし、これはまだ私のように歪んだ出力を与えます:
つまり、新しい行を印刷する必要があるたびに、新しいプログレスバーが次の行に印刷されます。ターミナル経由でスクリプトを実行しても、これは起こりません。どうすればこれを解決できますか?
ここ のように、tqdm
の代わりにtqdm_notebook
を使用してみてください。この段階では実験的ですが、ほとんどの場合はかなりうまくいきます。
これはインポートを次のように変更するのと同じくらい簡単です。
from tqdm import tqdm_notebook as tqdm
がんばろう!
編集:テスト後、tqdm
は実際にはJupyterノートブックの 'テキストモード'でうまく動きます。 最小の例 を指定していないのでわかりにくいですが、問題は各反復のprint文が原因であるように見えます。 print文は各ステータスバーの更新の間に数値(〜0.89)を出力しています。これは出力をめちゃくちゃにしています。 printステートメントを削除してみてください。
これは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に出力を受け取ると、最後の行を更新するだけなので戻って最初の行を更新しません。代わりに新しい行を書く必要があります。
1つの回避策は、代わりに両方を標準出力に出力することです。
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]
ここで私たちは木星が行の終わりまでクリアしていないように見えることがわかります。スペースを追加することで、それに対する別の回避策を追加できます。といった:
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つの出力を持たずに代わりに説明を更新する方が簡単かもしれません。
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がうまくいくのであれば、それを使ってください(でも、そう遠くないと思うかもしれません)。
ここで他のヒントがうまくいかず、私と同じようにprogress_apply
を通してpandas
統合を使っているのなら、tqdm
にそれを処理させることができます。
from tqdm.auto import tqdm
tqdm.pandas()
df.progress_apply(row_function, axis=1)
ここでの要点はtqdm.auto
モジュールにあります。 IPython Notebooksでの使用方法 で述べたように、これはtqdm
がJupyterノートブックとJupyterコンソールで使われているプログレスバーのフォーマットの間で選択するようにしますtqdm.auto
はpandas
でスムーズに機能しますが、progress_apply
は特にそうではありませんでした。