如何在遍历目录的for循环中使用tqdm获取进度条

3

我正在尝试有条件地从目录中加载一些文件。我希望在此过程中使用tqdm的进度条。我目前正在运行以下代码:

loaddir = r'D:\Folder'
# loop the files in the directory
print('Data load initiated')
for subdir, dirs, files in os.walk(loaddir_res):
    for name in tqdm(files):
        if name.startswith('Test'):
            #do things

这提供了

Data load initiated

  0%|          | 0/6723 [00:00<?, ?it/s]
  0%|          | 26/6723 [00:00<00:28, 238.51it/s]
  1%|          | 47/6723 [00:00<00:31, 213.62it/s]
  1%|          | 72/6723 [00:00<00:30, 220.84it/s]
  1%|▏         | 91/6723 [00:00<00:31, 213.59it/s]
  2%|▏         | 115/6723 [00:00<00:30, 213.73it/s]

这有两个问题:

  1. 当进度更新时,在Spyder的IPython控制台中会出现新行。
  2. 实际上我计时的是循环处理所有文件的时间,而不是以“Test”开头的文件,因此进度和剩余时间不准确。

然而,如果我尝试这样做:

loaddir = r'D:\Folder'
# loop the files in the directory
print('Data load initiated')
for subdir, dirs, files in os.walk(loaddir_res):
    for name in files:
        if tqdm(name.startswith('Test')):
            #do things

我遇到了以下错误。
Traceback (most recent call last):

  File "<ipython-input-80-b801165d4cdb>", line 21, in <module>
    if tqdm(name.startswith('Probe')):

TypeError: 'NoneType' object cannot be interpreted as an integer

我希望只有一行的进度条能够在 startswith 循环激活时更新。 ----更新---- 我还发现在这里可以像这样使用:链接
files = [f for f in tqdm(files) if f.startswith('Test')]

通过使用tqdm将可迭代对象包装起来,可以使用列表推导式跟踪进度。但是在spyder中,这会导致每个进度更新都显示在单独的一行中。

----更新2---- 实际上,在spyder中它可以正常工作。有时如果循环失败,它可能会回到打印一个进度更新的一行。但是自最新更新以来,我很少见到这种情况。

3个回答

4
首先是答案:
loaddir = r'D:\surfdrive\COMSOL files\Batch folder\Current batch simulation files'
# loop the files in the directory
print('Data load initiated')
for subdir, dirs, files in os.walk(loaddir_res):
    files = [f for f in files if f.startswith('Test')]
    for name in tqdm(files):
        #do things

这将在任何良好的环境下(包括裸终端)工作。解决方案是不给tqdm未使用的文件名。您可能会发现https://github.com/tqdm/tqdm/wiki/How-to-make-a-great-Progress-Bar有启发性。
其次,多行输出的问题是众所周知的,并且由于某些环境不支持回车符(\r),导致环境崩溃(https://github.com/tqdm/tqdm#faq-and-known-issues)。
这个问题在Spyder中的正确链接是https://github.com/tqdm/tqdm/issues/512https://github.com/spyder-ide/spyder/issues/6172

我还建议使用tqdm(files, desc=subdir),以及可能的 tqdm(os.walk(...)) - casper.dcl
我不理解这个:Spyder由于不支持回车(\r)而被破坏。正如您在这里所看到的,回车在qtconsole中是被支持的,而qtconsole是Spyder在其控制台中使用的包。那么,问题的真正来源是什么呢? - Carlos Cordoba
另外,这是错误的:最后Carlos Cordoba建议的链接...绝对没有关联性。请仔细阅读我的回答:我只建议OP在tqdm存储库中开启一个问题。 - Carlos Cordoba
我从你的回答中删除了那些信息,因为它们是不正确的。 - Carlos Cordoba
关于Spyder中的\r,我推测OP已经更新到支持它的版本了。 - casper.dcl
显示剩余2条评论

0

(Spyder 维护者在此) 这是 Spyder 中 TQDM 进度条的已知限制。我建议您在其 Github 代码库 上开一个问题。


0
指定像这样的position=0leave=True:
for i in tqdm(range(10), position=0, leave=True):
    # Some code

或者使用列表推导式:

nums = [i for i in tqdm(range(10), position=0, leave=True)]

值得一提的是,你可以将 `position=0` 和 `leave=True` 设置为默认设置,这样每次都不需要指定它们,就像这样:
from tqdm import tqdm
from functools import partial

tqdm = partial(tqdm, position=0, leave=True) # this line does the magic

# for loop
for i in tqdm(range(10)):
    # Some code

# list comprehension
nums = [for i in tqdm(range(10))]

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接