Jupyter Notebook中的tqdm反复打印新的进度条


138

我正在使用tqdm在Jupyter笔记本中运行的脚本打印进度。我正在通过将所有消息打印到控制台tqdm.write()。但是,这仍然给我这样的偏斜输出:

在此处输入图片说明

也就是说,每次必须打印新行时,新进度条都会打印在下一行上。通过终端运行脚本时不会发生这种情况。我该如何解决?


实际上,当我使用时tqdm_notebook,我什至可以执行normal print,并且不会影响进度栏。
Tomasz Gandor

Answers:


216

尝试使用tqdm.notebook.tqdm,而不是tqdm作为概述这里

这就像将导入更改为:

from tqdm.notebook import tqdm

祝好运!

编辑:经过测试,似乎tqdm在Jupyter笔记本中的“文本模式”下确实可以正常工作。很难说,因为您没有提供最小的示例,但是看来您的问题是由每次迭代中的打印语句引起的。在每个状态栏更新之间,print语句输出一个数字(〜0.89),这使输出混乱。尝试删除打印语句。


2
我没有使用过print()声明,而是使用过tqdm.write()。但是,tqdm_notebook效果很好。谢谢:)
Rohan Saxena

您知道它是否支持Python 3.6吗?我还没有碰运气
Jon

1
你遇到了什么错误?这对我来说可以。无法提供这么少的信息...您是否在jupyer中启用了ipywidgets?您只是简单地tqdm而不是tqdm_notebook?这在Python 3.6和Jupyter 1.0.0上运行良好。
oscarbranson

来自tqdm 4.19.4的tqdm_notebook正在Python 3.6,Jupyter笔记本5.0.0和ipywidgets 7.0.3上为我工作。
马特·克莱因史密斯

2
@ bugmenot123好收获,已修复。
Czyzby

39

对于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

问题是stdoutstderr的输出是异步处理的,并根据新行分别进行处理。

如果说Jupyter在stderr上接收第一行,然后在stdout上接收“已处理”输出。然后,一旦它在stderr上收到输出以更新进度,就不会返回并更新第一行,因为它只会更新最后一行。相反,它将不得不写一个新行。

解决方法1,写入stdout

一种解决方法是将两者都输出到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,改为设置描述

通常,没有两个输出而是更新描述可能更直接,例如:

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为您工作,请使用它(但是您可能不会读那么远)。


另一种方法是使用此progressbar stackoverflow.com/a/34482761/1207193
eusoubrasileiro

到目前为止,这是最好的答案。
拉斐

18

现在大多数答案已经过时了。如果正确导入tqdm,则更好。

from tqdm import tqdm_notebook as tqdm

在此处输入图片说明


7
它又变了:TqdmDeprecationWarning: This function will be removed in tqdm==5.0.0 Please use tqdm.notebook.tqdm instead of tqdm.tqdm_notebook

10

如果此处的其他技巧不起作用,并且-和我一样-您正在通过中使用pandas集成progress_apply,则可以进行tqdm处理:

from tqdm.autonotebook import tqdm
tqdm.pandas()

df.progress_apply(row_function, axis=1)

这里的重点在于tqdm.autonotebook模块。正如他们在IPython Notebook中使用的说明中所述,这使得tqdm可以在Jupyter笔记本和Jupyter控制台中使用的进度条格式之间进行选择-由于我这一方面仍缺乏进一步的研究,该特定格式选择的tqdm.autonotebook效果很好pandas,而所有其他格式都没有不是,progress_apply特别是。


9

要完成oscarbranson的答案:可以根据从何处运行进度条来自动选择控制台或笔记本版本的进度条:

from tqdm.autonotebook import tqdm

更多信息可以在这里找到


8

以上都不适合我。我发现运行以下命令可以在出现错误后解决此问题(它只会清除后台进度条的所有实例):

from tqdm import tqdm

# blah blah your code errored

tqdm._instances.clear()

1
谢谢!但是,如果不存在实例,它将引发错误。仍然希望将其与脚本和Hydrogen IDE一起使用。这是我的代码。 try: # Avoids problem on notebooks / Hydrogen IDE tqdm.tqdm._instances.clear() except Exception: pass
雅克·皮特斯

是的,如果不存在实例,它将抛出异常。您的除尝试方法是否存在问题?
James Owers


0

对于在Windows上无法解决此处提到的任何解决方案重复栏问题的每个人。我必须按照修复该问题的tqdm已知问题中的colorama说明安装该软件包。

pip install colorama

通过以下示例进行尝试:

from tqdm import tqdm
from time import sleep

for _ in tqdm(range(5), "All", ncols = 80, position = 0):
    for _ in tqdm(range(100), "Sub", ncols = 80, position = 1, leave = False):
        sleep(0.01)

会产生类似:

All:  60%|████████████████████████                | 3/5 [00:03<00:02,  1.02s/it]
Sub:  50%|██████████████████▌                  | 50/100 [00:00<00:00, 97.88it/s]
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.