keisukeのブログ

***乱雑です!自分用のメモです!*** 統計や機械学習の勉強と、読み物を書く練習と、備忘録用のブログ

【Python】 progressbar

進捗を示すためにshell上にプログレスバーを表示したいことがよくあります.

50% (200 of 400) |############            |

こんなやつです.

Pythonでも,重い処理をforループで回すときに欲しくなります. 当然同じことを考える人がいるので,すでにパッケージがあります.

python progressbar」で検索して一番上に出てくるパッケージ(progressbar)はpython3に対応してない上,開発がだいぶ前に止まっているので,今回は別のパッケージ(progressbar2)を使います.

インストール

pip install progressbar2

[^1 : Mac/Linuxの人はsudo pip install progressbar2]

使い方

例1:オプション無しのデフォルト挙動
>>> from progressbar import ProgressBar
>>> import time

>>> p = ProgressBar(100)  # 最大値100

>>> for i in range(100):
>>>     p.update(i+1)  # ProgressBarの表示に合わせて+1
>>>     time.sleep(0.01)  # 0.01秒スリープ

100% (100 of 100) |########################| Elapsed Time: 0:00:01 ETA:  0:00:00

Elapsed Timeはそのまま消費時間、 一番右のETAは、実行してみればわかると思いますが、estimate the time of arrival、 推定残り時間です。

例2:パーセンテージとバーだけ
>>> from progressbar import ProgressBar, Percentage, Bar
>>> import time

>>> p = ProgressBar(widgets=[Percentage(), Bar()], maxval=100).start()
>>> for i in range(100):
>>>     p.update(i+1)
>>>     time.sleep(0.01)
>>> p.finish()

100%|##########################################################################|
例3:ファイル転送っぽく
>>> from progressbar import ProgressBar, Percentage, Bar
>>> import time

>>> widgets = ['Test: ', Percentage(), ' ', Bar(marker=RotatingMarker()),
               ' ', ETA(), ' ', FileTransferSpeed()]
>>> p = ProgressBar(widgets=widgets, maxval=1000).start()
>>> for i in range(1000):
>>>     p.update(i+1)
>>>     time.sleep(0.001)


Test: 100% ||||||||||||||||||||||||||||||||||||||||||| ETA:  0:00:00 906.16  B/s
例4:今何番目を処理してるのかだけ
>>> from progressbar import ProgressBar, SimpleProgress
>>> import time

>>> p = ProgressBar(widgets=[SimpleProgress()], maxval=100).start()
>>> for i in range(100):
>>>     p.update(i+1)
>>>     time.sleep(0.01)
>>> p.finish()

100 of 100  
例5:最大値を明示的に渡さない
>>> from progressbar import ProgressBar
>>> import time

>>> p = ProgressBar()
>>> for i in p(range(100)):
>>>     p.update(i+1)
>>>     time.sleep(0.01)

100% (100 of 100) |########################| Elapsed Time: 0:00:01 Time: 0:00:01

一番よく使いそうなのは例5ですが,イテレータをProgressBarにとられてしまうので,任意のイテレータで回すforループでプログレスバーを表示したいときは例1か例2のようにすることが多そうです. 例2は表示がシンプルな割にやっていることが例1よりも複雑なので,結局例5と例1だけを使えば良さそうです.