tqdm分块处理序列时如何配置显示准确的条目数进度条
tqdm分块处理场景下按实际条目数展示进度的方案
问题背景
对序列做分块处理时,最后一个分块的长度通常小于预设分块大小,默认tqdm写法仅统计分块数量,无法满足以下需求:
- 进度条统计维度为已处理的条目数,而非分块数
- 进度百分比计算准确,无溢出超100%的问题
- 进度最大值显示为真实总条目数,而非按分块大小向上取整的数值
初始写法的问题
最直观的默认写法仅统计分块数,不符合需求:
import tqdm, math total=567 chunkSize=100 # 每次处理i0到min(i0+chunkSize, total)区间的条目 for i0 in tqdm.tqdm(range(0,total,chunkSize)): pass
运行输出总进度为6个分块,完全没有体现实际条目处理进度:
100%|█████████████████████████████████| 6/6 [00:00<00:00, 75121.86it/s]
参数调整尝试的缺陷
后续尝试通过调整tqdm参数解决问题的三种写法均存在问题:
# 尝试1 for i0 in tqdm.tqdm(range(0,total,chunkSize),unit_scale=chunkSize,total=total/chunkSize): pass # 尝试2 for i0 in tqdm.tqdm(range(0,total,chunkSize),unit_scale=float(chunkSize),total=total/chunkSize): pass # 尝试3 for i0 in tqdm.tqdm(range(0,total,chunkSize),unit_scale=chunkSize,total=math.ceil(total/chunkSize)): pass
三者运行输出分别为:
# 尝试1:进度溢出至106%,触发官方警告 106%|██████████████████████████████████| 600.0/567.0 [00:00<00:00, 6006163.25it/s] # 尝试2:进度溢出至106%,触发官方警告 106%|██████████████████████████████████| 600/567.0 [00:00<00:00, 5264816.74it/s] # 尝试3:总进度显示为600,和实际总条目数567不符 100%|██████████████████████████████████| 600/600 [00:00<00:00, 4721542.96it/s]
前两种写法会触发tqdm/std.py:533: TqdmWarning: clamping frac to range [0, 1]警告,第三种总数值不符合真实情况,均无法满足需求。
可行实现方案
不要依赖unit_scale参数做自动换算,手动初始化tqdm实例时直接将total设为真实总条目数,每处理完一个分块,按当前分块的实际长度更新进度即可,完美适配最后一个分块长度不足的场景。
基础写法:
import tqdm total = 567 chunk_size = 100 pbar = tqdm.tqdm(total=total, unit="条") for i0 in range(0, total, chunk_size): # 计算当前分块的真实长度,最后一个分块自动取剩余条目数 curr_chunk_len = min(chunk_size, total - i0) # 此处执行当前分块的处理逻辑 # 按实际处理的条目数更新进度 pbar.update(curr_chunk_len) pbar.close()
更简洁的上下文管理器写法(推荐,自动处理进度条关闭逻辑):
import tqdm total = 567 chunk_size = 100 with tqdm.tqdm(total=total, unit="条") as pbar: for i0 in range(0, total, chunk_size): curr_chunk_len = min(chunk_size, total - i0) # 此处执行当前分块的处理逻辑 pbar.update(curr_chunk_len)
实现效果
运行后完全满足所有需求:
- 进度统计的是实际处理的条目数量,而非分块数
- 进度累加值刚好等于总条目数,百分比计算准确,永远不会出现超过100%的情况
- 进度条最大值显示为真实总条目数567,不存在向上取整的偏差
示例输出:
100%|█████████████████████████████████| 567/567 [00:00<00:00, 132764.29条/s]
内容的提问来源于stack exchange,提问作者eudoxos
相关产品推荐
相关产品推荐

