如何用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()
关键细节说明
- 进程池 vs 线程池:图像处理属于CPU密集型任务,用
ProcessPoolExecutor能绕过Python的GIL限制,充分利用多核CPU的优势;如果你的处理以IO操作为主(比如大量读写文件),换成ThreadPoolExecutor也可以。 - 顺序稳定性:
os.listdir返回的文件顺序可能不确定,如果需要固定的90%/10%分配规则,记得先对all_img_paths排序(比如按文件名排序)。 - 参数打包:把所有需要的参数都塞进元组里,确保处理函数能拿到判断目录所需的所有信息(索引、总数量、两个目标目录)。
内容的提问来源于stack exchange,提问作者snowe
相关产品推荐
相关产品推荐

