Python中的双进度条

时间:2014-04-16 15:14:42

标签: python progress-bar

有没有办法在Python中创建双进度条? 我想在彼此内部运行两个循环。对于每个循环,我想要一个进度条。我的程序看起来像:

import time
for i1 in range(5):
    for i2 in range(300):
        # do something, e.g. sleep
        time.sleep(0.01)
        # update upper progress bar
    # update lower progress bar

中间某处的输出应该看起来像

50%|############################                                  |ETA: 0:00:02
80%|##################################################            |ETA: 0:00:04

现有的非常酷progressbar模块似乎不支持。

7 个答案:

答案 0 :(得分:21)

使用nested progress bars feature of tqdm,这是一个极低开销,可自定义的进度条库:

$ pip install -U tqdm

然后:

from tqdm import tqdm
import time
for i1 in tqdm(range(5)):
    for i2 in tqdm(range(300)):
        # do something, e.g. sleep
        time.sleep(0.01)

您也可以使用from tqdm import trange,然后将tqdm(range(...))替换为trange(...)。你也可以得到working in a notebook

答案 1 :(得分:7)

需要你移动光标位置。我写了一个hacky的东西来做它。

此脚本依赖于progressbar模块假定您处于一个新线以绘制进度条的事实。只需向上移动光标(使用'#34的转义码;向上移动光标1行")和向下移动(仅使用换行符。我也可以使用转义码,但换行更容易,更快),一个人可以保持多个进度条。

import progressbar, time, sys

def up():
    # My terminal breaks if we don't flush after the escape-code
    sys.stdout.write('\x1b[1A')
    sys.stdout.flush()

def down():
    # I could use '\x1b[1B' here, but newline is faster and easier
    sys.stdout.write('\n')
    sys.stdout.flush()

# Total bar is at the bottom. Move down to draw it
down()
total = progressbar.ProgressBar(maxval=50)
total.start()

for i in range(1,51):
    # Move back up to prepare for sub-bar
    up()

    # I make a new sub-bar for every iteration, thinking it could be things
    # like "File progress", with total being total file progress.
    sub = progressbar.ProgressBar(maxval=50)
    sub.start()
    for y in range(51):
        sub.update(y)
        time.sleep(0.005)
    sub.finish()

    # Update total - The sub-bar printed a newline on finish, so we already
    # have focus on it
    total.update(i)
total.finish()

这当然有点hacky,但它完成了工作。我希望它很有用。

答案 2 :(得分:2)

使用enlighten

import time
import enlighten

manager = enlighten.get_manager()
ticks = manager.counter(total=100, desc="Ticks", unit="ticks", color="red")
tocks = manager.counter(total=20, desc="Tocks", unit="tocks", color="blue")

for num in range(100):
    time.sleep(0.1)  # Simulate work
    print("The quick brown fox jumps over the lazy dog. {}".format(num))
    ticks.update()
    if not num % 5:
        tocks.update()

manager.stop()

enter image description here

答案 3 :(得分:2)

游戏有点晚了,但这里有一个只使用 tqdm 的答案

import re
from time import sleep
from tqdm import trange

class DescStr:
    def __init__(self):
        self._desc = ''

    def write(self, instr):
        self._desc += re.sub('\n|\x1b.*|\r', '', instr)

    def read(self):
        ret = self._desc
        self._desc = ''
        return ret

    def flush(self):
        pass


rng_a = trange(10)
desc = DescStr()
for x in rng_a:
    for y in trange(10, file=desc, desc="Y"):
        rng_a.set_description(desc.read())
        sleep(0.1)

产生:

Y:  90%|######### | 9/10 [00:00<00:00,  9.55it/s]: 100%|##########| 10/10 [00:10<00:00,  

答案 4 :(得分:0)

使用atpbar可以轻松完成。

例如:

import time, random
from atpbar import atpbar

for i in atpbar(range(4), name='outer'):
    n = random.randint(1000, 10000)
    for j in atpbar(range(n), name='inner {}'.format(i)):
        time.sleep(0.0001)

上面的代码嵌套了for个循环。外循环迭代四次。对于外循环的每次迭代,内循环迭代随机选择的次数。内部循环的进度条在循环完成时向上移动。活动进度条保持在底部。进度条的快照可能看起来像

 100.00% :::::::::::::::::::::::::::::::::::::::: |     3287 /     3287 |:  inner 0
 100.00% :::::::::::::::::::::::::::::::::::::::: |     5850 /     5850 |:  inner 1
  50.00% ::::::::::::::::::::                     |        2 /        4 |:  outer  
  34.42% :::::::::::::                            |     1559 /     4529 |:  inner 2

答案 5 :(得分:0)

我基本上只想添加到@ casper.dcl的答案。在稍微不同的情况下,如果您有两个嵌套的for循环,并且只需要一个进度条,则可以执行以下操作。

from tqdm import tqdm
import time
n = 5
m = 300
with tqdm(total=n * m) as pbar:
    for i1 in tqdm(range(n)):
        for i2 in tqdm(range(m)):
            # do something, e.g. sleep
            time.sleep(0.01)
            pbar.update(1)

我知道这不是问题所在,但对某些人来说还是有帮助的。

答案 6 :(得分:0)

this answer的启发,我还尝试了enlighten python库并编写了简单的帮助程序.txt来包装迭代器(代码顶部),并提供了用法示例(代码底部)以及终端直播。

在Linux和Windows中都是彩色的。

pit

asciicast