如何设置tqdm的r_bar部分

jot*_*tbe 5 python-3.x tqdm

我使用 tqdm 打印带有 hyperopt 的长时间运行优化过程的进度条。这个过程调用一个函数 500 次,每次调用大约需要 10 到 20 分钟,所以我开始让进度显示更精细一点,并tqdm.update在循环中添加了一些 -语句,逐步推进进度条以避免有两个嵌套的进度条,同时仍然能够立即看到到目前为止执行了多少函数调用。

现在丑陋的结果是这样的:

 15%|????                    | 73.69999999999993/500 [7:40:31<102:54:08, 868.98s/it, evaluating fold 2 of  2 folds...]Iteration 1, loss = 2.50358388
Run Code Online (Sandbox Code Playgroud)

你可以在上面看到,这是函数的第 73 次调用,第 73 次函数调用大约完成了 70%。事实上,我只是估计了m函数中子步骤的数量(可能因调用而异)并使用分数1/m来更新进度条。然后在函数调用之后,我只是将进度条同步回一个完整的整数,以避免添加舍入错误。

当然,准确性在这里根本不是问题。但我想显示 73.70 而不是 73.69999999999993。我已经尝试将我的更新值四舍五入到两个小数位,这并不能解决问题,因为浮点数的精度问题,如果一个数字不能完全用浮点数表示,那么它又变得丑陋了。根据tqdm文档,这部分隐藏在r_bar整个格式字符串的部分中,但我找不到设置它的方法。你能帮我解决这个问题吗?

根据文档r_bar默认为:

r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, '
Run Code Online (Sandbox Code Playgroud)

这是我的代码:

with tqdm(iterable=None, initial=num_trials, maxinterval=maxinterval, total=max_evals, ascii=False, disable=show_progressbar is False) as progress_bar:
    def fn_to_minimize(*args, **kwargs):
        return fn(*args, **kwargs, _progress_bar=progress_bar)

    for num_trials in range(num_trials, max_evals):
        progress_bar.n=float(num_trials)
        progress_bar.refresh()
        best = fmin(**kwargs, fn=fn_to_minimize, trials=trials, max_evals=num_trials+1)

# do some other stuff here
Run Code Online (Sandbox Code Playgroud)

在被调用的函数(kwargs顺便说一句中的条目之一)中,我像这样更新进度条:

_progress_bar.update(round(update_value, 2))
Run Code Online (Sandbox Code Playgroud)

Axo*_*ois 8

对于 中的舍入问题tqdm,您可以直接编辑 中的格式r_bar作为 中的参数之一bar_format。例如:

from tqdm import trange
for i in trange(int(7e7), bar_format = "{desc}: {percentage:.3f}%|{bar}| {n_fmt}/{total_fmt} [{elapsed}<{remaining}"):
    pass
Run Code Online (Sandbox Code Playgroud)

显示:在此输入图像描述

对于 2 位小数,您可以简单地将 编辑{n_fmt}{n:.2f}。您还可以编辑其他参数,例如{desc}或向percentage.

from tqdm import trange
for i in trange(int(7e7), bar_format = "{desc}: {percentage:.10f}%|{bar}| {n:.2f}/{total_fmt} [{elapsed}<{remaining}"):
    pass
Run Code Online (Sandbox Code Playgroud)

显示: 在此输入图像描述

查看 的源代码后tqdmn_fmt实际上指向str(n),因此传入 的格式化版本n可以绕过其内在格式。

if unit_scale:
            n_fmt = format_sizeof(n, divisor=unit_divisor)
            total_fmt = format_sizeof(total, divisor=unit_divisor) \
                if total is not None else '?'
        else:
            n_fmt = str(n)
            total_fmt = str(total) if total is not None else '?'

        try:
            postfix = ', ' + postfix if postfix else ''
        except TypeError:
            pass
Run Code Online (Sandbox Code Playgroud)

  • 顺便提一句。因此,我学会了“Decimal”类:-),尽管这些知识对我没有帮助(这将是一个丑陋的解决方案,而且 tqdm 似乎不喜欢小数)也许我可以在其他地方使用它。 (2认同)