You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用concurrent.futures的.map()按比例分流保存处理后的图像

解决concurrent.futures.map()中按比例分配保存目录的问题

嘿,这个问题我之前也碰到过——concurrent.futures.map()确实不会主动给你传递每个任务的索引,但咱们可以换个思路,把图像路径和它的索引打包成元组一起传给处理函数,这样就能在函数里轻松判断该存到哪个目录啦!

核心思路

既然map()只能传递单个参数给处理函数,那我们就把所有需要的信息(索引、图像路径、总图像数、两个保存目录)打包成一个元组,让map()逐个传递这些元组给处理函数。这样处理函数就能拿到索引,和总数量的90%做对比,选择对应的保存路径。

具体代码示例

假设我们用PIL处理图像,这里给出完整的可运行代码:

import os
from concurrent.futures import ProcessPoolExecutor
from PIL import Image

def process_and_save_image(task_args):
    # 解包传入的参数
    idx, img_path, total_imgs, save_dir_90, save_dir_10 = task_args
    
    # ----------------------
    # 这里替换成你的图像处理逻辑
    with Image.open(img_path) as img:
        # 示例:转为RGB格式,你可以换成裁剪、resize、滤波等操作
        processed_img = img.convert("RGB")
    # ----------------------
    
    # 判断保存目录
    if idx < total_imgs * 0.9:
        target_dir = save_dir_90
    else:
        target_dir = save_dir_10
    
    # 确保目标目录存在(不存在则创建)
    os.makedirs(target_dir, exist_ok=True)
    
    # 构造保存路径(保留原文件名)
    save_filename = os.path.basename(img_path)
    save_path = os.path.join(target_dir, save_filename)
    
    # 保存处理后的图像
    processed_img.save(save_path)

def main():
    # 配置你的路径
    input_image_dir = "/path/to/your/input/images"
    dir_for_90percent = "/path/to/save/90_percent_images"
    dir_for_10percent = "/path/to/save/10_percent_images"
    
    # 获取所有图像路径(这里筛选常见图像格式,可根据需求调整)
    all_img_paths = [
        os.path.join(input_image_dir, filename)
        for filename in os.listdir(input_image_dir)
        if filename.lower().endswith((".jpg", ".jpeg", ".png", ".bmp"))
    ]
    
    # 总图像数量
    total_images = len(all_img_paths)
    
    # 可选:如果需要稳定的分配顺序,先对图像路径排序
    all_img_paths.sort()
    
    # 打包每个任务的参数:(索引, 图像路径, 总数量, 90%目录, 10%目录)
    task_list = [
        (idx, img_path, total_images, dir_for_90percent, dir_for_10percent)
        for idx, img_path in enumerate(all_img_paths)
    ]
    
    # 使用进程池执行(图像处理是CPU密集型,进程池更高效)
    with ProcessPoolExecutor() as executor:
        executor.map(process_and_save_image, task_list)

if __name__ == "__main__":
    main()

关键细节说明

  1. 进程池 vs 线程池:图像处理属于CPU密集型任务,用ProcessPoolExecutor能绕过Python的GIL限制,充分利用多核CPU的优势;如果你的处理以IO操作为主(比如大量读写文件),换成ThreadPoolExecutor也可以。
  2. 顺序稳定性:os.listdir返回的文件顺序可能不确定,如果需要固定的90%/10%分配规则,记得先对all_img_paths排序(比如按文件名排序)。
  3. 参数打包:把所有需要的参数都塞进元组里,确保处理函数能拿到判断目录所需的所有信息(索引、总数量、两个目标目录)。

内容的提问来源于stack exchange,提问作者snowe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.11 08:17:01