196

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

在此处输入图像描述

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

4

11 回答 11

309

尝试使用tqdm.notebook.tqdm而不是,如此tqdm所述。

这可以像将导入更改为一样简单:

from tqdm.notebook import tqdm

祝你好运!

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

于 2017-02-14T05:41:12.987 回答
48

这是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,写入标准输出

一种解决方法是将两者都输出到标准输出:

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

于 2017-11-09T11:22:08.430 回答
33

现在大多数答案都已过时。如果正确导入tqdm 会更好。

from tqdm import tqdm_notebook as tqdm

在此处输入图像描述

于 2020-02-11T07:53:18.277 回答
16

如果此处的其他提示不起作用并且 - 就像我一样 - 您正在使用pandas集成progress_apply,您可以让tqdm处理它:

from tqdm.autonotebook import tqdm
tqdm.pandas()

df.progress_apply(row_function, axis=1)

这里的重点在于tqdm.autonotebook模块。正如他们在 IPython Notebooks 中使用的说明中所述,这使得tqdm在 Jupyter 笔记本和 Jupyter 控制台中使用的进度条格式之间进行选择 - 由于我方面仍然缺乏进一步调查的原因,选择的特定格式在tqdm.autonotebook中运行顺利pandas,而所有其他格式都没有't,progress_apply具体来说。

于 2019-04-21T18:20:50.440 回答
16

要完成 oscarbranson 的回答:可以根据运行的位置自动选择控制台或笔记本版本的进度条:

from tqdm.autonotebook import tqdm

更多信息可以在这里找到

于 2019-10-30T13:01:31.597 回答
15

以上都不适合我。我发现在出错后运行以下排序此问题(它只是清除后台进度条的所有实例):

from tqdm import tqdm

# blah blah your code errored

tqdm._instances.clear()
于 2020-02-05T01:38:13.503 回答
6

对于在 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]
于 2020-04-06T20:30:42.407 回答
0

使用 tqdm_notebook

from tqdm import tqdm_notebook as tqdm

x=[1,2,3,4,5]

for i in tqdm(range(0,len(x))):

    print(x[i])
于 2020-04-01T13:24:47.210 回答
0

另一个使用 tqdm 的进度条示例

      from tqdm import tqdm
      my_list = list(range(100))
      with tqdm(total=len(my_list)) as pbar:
          for x in my_list:
             pbar.update(1)
于 2021-06-06T06:33:03.523 回答
0

在我的情况下,我只需要更新 ipywidgets 以在使用常规时摆脱额外的打印from tqdm import tqdm

于 2022-02-17T16:41:35.940 回答
0

使用Python 3.9.2tqdm==4.62.3

from tqdm.notebook import tqdm

for item in tqdm(list_of_items):
    do_something(item)
于 2022-03-03T18:56:21.733 回答