package1 | cabbage

cabbage

菜鸟写给小白的教程

0%

package1

tqdm

Tqdm 是一个快速,可扩展的Python进度条,可以在 Python 长循环中添加一个进度提示信息,用户只需要封装任意的迭代器 tqdm(iterator)。

安装与导入

pip install tqdm

我们能发现使用的核心是tqdm和trange这两个函数,导入这两个

from tqdm import tqdm

from tqdm import trange

其实:trange=tqdm(range())

4种使用方式

tqdm是非常通用的,并且可以以多种方式使用。下面给出三个主要部分。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# 方法1
for i in tqdm(可迭代对象):
pass

# 方法2
for idx, i in enumerate(tqdm(可迭代对象)):
pass
for idx, i in tqdm(enumerate(可迭代对象)):
pass

# 方法3 而如果想要在迭代过程中变更说明文字,还可以预先实例化进度条对象,在需要刷新说明文字的时候执行相应的程序
p = tqdm(可迭代对象)
for idx, i in enumerate(p):
pass
# 方法4 手动控制更新
with tqdm.tqdm(total=10) as bar: # total为进度条总的迭代次数
# 操作1
time.sleep(1)
# 更新进度条
bar.update(1) # bar.update()里面的数表示更新的次数,和optimizer.step方法类似

# 操作2
time.sleep(2)
# 更新进度条
bar.update(3)

# 操作3
time.sleep(1)
# 更新进度条
bar.update(6) # 建议不要超过total

with tqdm(total=100) as pbar:
for i in range(10):
pbar.update(10)
# 也可以这样
pbar = tqdm(total=100)
for i in range(10):
pbar.update(10)
pbar.close()

3

而如果想要在迭代过程中变更说明文字,还可以预先实例化进度条对象,在需要刷新说明文字的时候执行相应的程序:

tqdm提供了两个个方法:

  1. set_description()
  2. set_postfix()

这两个方法就类似于print,可以在进度条中显示一些变动的信息,在使用set_description()和set_postfix()时一般会创建一个tqdm.tqdm()对象

1
2
3
4
5
6
pbar = tqdm.tqdm(range(epochs), ncols=100)  # ncols设置进度条显示的字符长度,小了就显示不全了

for idx, element in enumerate(pbar):
time.sleep(0.01)
pbar.set_description(f"Epoch {idx}/{epochs}")
pbar.set_postfix({"class": element}, loss=random.random(), cost_time = random.randrange(0, 100))
image-20230328122422753

4

tqdm()的返回值是一个可迭代对象,迭代的每一个元素就是iterable的每一个参数。该返回值可以修改进度条信息。示例

1
2
3
4
5
with tqdm(range(100), desc='Test') as tbar:
for i in tbar:
tbar.set_postfix(loss=i/100, x=i)
tbar.update() # 默认参数n=1,每update一次,进度+n
time.sleep(0.2)

参数

1
2
3
4
@staticmethod
def format_meter(n, total, elapsed, ncols=None, prefix='', ascii=False, unit='it',
unit_scale=False, rate=None, bar_format=None, postfix=None,
unit_divisor=1000, initial=0, colour=None, **extra_kwargs):

iterable: 可迭代的对象, 在手动更新时不需要进行设置
desc: 字符串,左边进度条描述,作为进度条标题
total: 预期的迭代次数。一般不填,默认为iterable的长度。
leave: bool值, 迭代完成后是否保留进度条。默认保留。
file: 输出指向位置, 默认是终端, ⼀般不需要设置
ncols: 调整进度条宽度, 默认是根据环境⾃动调节长度, 如果设置为0, 就没有进度条, 只有输出的信息
unit: 描述处理项⽬的⽂字, 默认是it, 例如: 100 it/s, 处理照⽚的话设置为img ,则为 100 img/s
unit_scale: ⾃动根据国际标准进⾏项⽬处理速度单位的换算, 例如 100000 it/s >> 100k it/s

postfix进度条后缀信息以字典形式传入详细信息

colour: 进度条颜色

还有一个复杂的格式参数bar_formmat,见下一节

进度条含义解释与自定义

其中xxxit/s表示每秒迭代的次数,it=iteration(一次迭代)

进度百分比|进度条| 当前迭代数/总迭代个数,[消耗时间<剩余时间,迭代的速度]

其会在每一轮从可迭代对象中取得一个值之后,打印遍历进度条,然后再执行循环中的程序。最后面的速度表示执行一个循环所耗费的时间。

复杂参数bar_formmat

默认格式:'{l_bar}{bar}{r_bar}'

l_bar:进度条左边的文字
bar: 进度条图形部分
r_bar: 进度条右边的文字

bar_format  : str, optional
    Specify a custom bar string formatting. May impact performance.
    [default: '{l_bar}{bar}{r_bar}'], where
    l_bar='{desc}: {percentage:3.0f}%|' and
    r_bar='| {n_fmt}/{total_fmt} [{elapsed}<{remaining}, {rate_fmt}{postfix}]'
Possible vars: l_bar, bar, r_bar, n, n_fmt, total, total_fmt,
    percentage, elapsed, elapsed_s, ncols, desc, unit,
    rate, rate_fmt, rate_noinv, rate_noinv_fmt,
    rate_inv, rate_inv_fmt, postfix, unit_divisor,
    remaining, remaining_s.
    Note that a trailing ": " is automatically removed after {desc}
    if the latter is empty.

其具体为:{desc}: 100%|███████████| 10/10 [00:05<00:00, 1.98it/s,{postfix}]

desc、postfix默认为空;

1
2
for i in tqdm(range(10), bar_format='{desc}|{bar}|{percentage:3.0f}%'):
time.sleep(.5)

|█████████████████████|100%

others

嵌套

1
2
3
4
5
tqdm还支持在循环中嵌套使用进度条,例如在for循环中嵌套while循环:
from tqdm import tqdm
for i in tqdm(range(10)):
for j in tqdm(range(100), leave=False):
# do something

这样就会在外层循环中显示一个进度条,在内层循环中显示另一个进度条。参数leave用于控制内层进度条是否在外层进度条完成后消失。

在多线程和多进程中使用

可以通过设置参数desc来给每个进程或线程命名

1
2
3
4
5
6
7
8
9
10
11
from tqdm import tqdm
import multiprocessing

def worker(num):
for i in tqdm(range(1000000), desc=f'Worker {num}'):
pass

if __name__ == '__main__':
with multiprocessing.Pool(4) as p:
p.map(worker, [1, 2, 3, 4])

这样就会在每个进程的进度条上显示进度,并显示进程的名称。

结合pandas的使用

1
2
3
4
5
6
import  pandas as pd
import numpy as np

df = pd.DataFrame(np.random.randint(0, 100, (10000000, 6)))
tqdm.pandas(desc="my bar!")
df.progress_apply(lambda x: x**2)
1
2
3
4
5
6
7
8
9
tqdm对pandas中的apply也提供了支持,用法是:

import pandas as pd
from tqdm.notebook import tqdm
# 每个单独的porgress_apply运行之前一定要先执行tqdm.pandas()
tqdm.pandas()

df=pd.DataFrame({'a', range(10)})
x = df.progress_apply(lambda x: time.sleep(0.2))

减少tqdm进度条在日志文件中的打印频率?

可以使用嵌套循环,其中包含tqdm的循环和内部循环只是一个简单的for循环

1
2
3
for outer in tqdm(range(0,1e5,1e4)):
for inner in range(1e4):
print(outer+inner)

cankao

https://blog.csdn.net/weixin_44878336/article/details/124894210

https://www.cnblogs.com/KuanLez/p/15974970.html

https://blog.csdn.net/weixin_42475060/article/details/121661840

https://blog.csdn.net/qq_41554005/article/details/117297861

https://blog.csdn.net/winter2121/article/details/111356587

https://zhuanlan.zhihu.com/p/378474516