基于CSV图片标签创建分类子文件夹并移动图片的报错排查
按标签分类移动图片到对应子文件夹问题修复
需求背景
需要为每个图像类别创建独立子文件夹,将对应类别的图片从全量存储的总文件夹中移动进去,现有资源如下:
- 存放所有全量图片的
data文件夹 - 标注文件
labels.csv,包含image_id、label两个核心字段 - 当前项目根目录结构:
- data
- img1.jpg
- img2.jpg
- 其余图片文件
- labels.csv
- notebook.ipynb
- data
初始代码与报错信息
初始实现代码
import shutil, os import pandas as pd labels = pd.read_csv("labels.csv") labels = labels.sort_values('Manu_Series_Year') class_names = list(labels.Manu_Series_Year.unique()) train_images = 'train' train_cat = 'train_' # 创建子文件夹 for i in class_names: os.makedirs(os.path.join('train_', i)) # 移动图片到对应类别文件夹 for c in class_names: # 类别名 for i in list(labels[labels['Manu_Series_Year']==c]['Image_id']): # 图片ID get_image = os.path.join('train', str(i)) # 图片路径 move_image_to_cat = shutil.move(get_image, 'train_/'+c)
报错日志
Traceback --------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\shutil.py in move(src, dst, copy_function) 813 try: --> 814 os.rename(src, real_dst) 815 except OSError: FileNotFoundError: [WinError 3] 系统无法找到指定路径: 'C://Users/deniz/OneDrive/MA/Dataset/archive_unbekannt/train\\1' -> 'C://Users/deniz/OneDrive/MA/Dataset/archive_unbekannt/train_/Acura ILX 2013' During handling of the above exception, another exception occurred: FileNotFoundError Traceback (most recent call last) <ipython-input-28-8d99c8eb764e> in <module> 18 for i in list(labels[labels['Manu_Series_Year']==c]['Image_id']): # 图片ID 19 get_image = os.path.join('C://Users/deniz/OneDrive/MA/Dataset/archive_unbekannt/train', str(i)) # 图片路径 --- > 20 move_image_to_cat = shutil.move(get_image, 'C://Users/deniz/OneDrive/MA/Dataset/archive_unbekannt/train_/'+c) C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\shutil.py in move(src, dst, copy_function) 832 rmtree(src) 833 else: -- > 834 copy_function(src, real_dst) 835 os.unlink(src) 836 return real_dst C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\shutil.py in copy2(src, dst, follow_symlinks) 441 if os.path.isdir(dst): 442 dst = os.path.join(dst, os.path.basename(src)) -- > 443 copyfile(src, dst, follow_symlinks=follow_symlinks) 444 copystat(src, dst, follow_symlinks=follow_symlinks) 445 return dst C:\Program Files\WindowsApps\PythonSoftwareFoundation.Python.3.9_3.9.2032.0_x64__qbz5n2kfra8p0\lib\shutil.py in copyfile(src, dst, follow_symlinks) 263 else: 264 try: -- > 265 with open(src, 'rb') as fsrc, open(dst, 'wb') as fdst: 266 # macOS 267 if _HAS_FCOPYFILE: FileNotFoundError: [Errno 2] No such file or directory: 'train\\1'
错误原因分析
初始代码核心错误
- 源路径配置不匹配:代码中写的图片源文件夹是
train,但实际存放所有图片的文件夹是data,系统无法找到对应路径下的图片文件 - 路径分隔符处理不统一:创建子文件夹时使用了适配跨系统的
os.path.join,但移动图片时直接用/拼接路径,Windows系统下容易出现路径识别错误 - 路径前缀和实际项目结构完全不匹配
第一次修改后仍报错的原因
第一次修改代码如下:
import shutil, os import pandas as pd labels = pd.read_csv("labels.csv") labels = labels.sort_values('Manu_Series_Year') class_names = list(labels.Manu_Series_Year.unique()) train_images = 'data' train_cat = 'data_' # 创建子文件夹 for c in class_names: dest = 'data_' + c os.makedirs(c) for i in list(labels[labels['Manu_Series_Year']==c]['Image_id']): # 图片ID get_image = os.path.join('data', str(i)) # 图片路径 move_image_to_cat = shutil.move(get_image, dest)
本次修改虽然修正了源路径为data,但仍存在核心问题:
目标路径逻辑错误:dest = 'data_' + c 是直接生成和data同级的、带前缀的类别文件夹,不是在统一的分类根目录下创建子文件夹,且os.makedirs(c)创建的是无前缀的类别文件夹,和dest路径完全不一致,移动图片时系统找不到目标文件夹。
最终可运行代码
import shutil, os import pandas as pd # 读取标注文件 labels = pd.read_csv("labels.csv") # 按类别字段排序 labels = labels.sort_values('Manu_Series_Year') # 提取所有唯一类别名 class_names = list(labels.Manu_Series_Year.unique()) # 源图片文件夹路径 train_images = 'data' # 分类存储的根文件夹前缀 train_cat = 'data_' # 创建子文件夹并移动图片 for c in class_names: # 拼接目标类别子文件夹路径,统一放在data_根目录下 dest = 'data_/' + c os.makedirs(dest) # 遍历当前类别下的所有图片ID for i in list(labels[labels['Manu_Series_Year']==c]['Image_id']): # 拼接源图片完整路径 get_image = os.path.join('data', i) # 移动图片到对应类别子文件夹 shutil.move(get_image, dest)
可选优化:可以给
os.makedirs添加exist_ok=True参数,避免重复运行时因为文件夹已存在报错;也可以在移动前加os.path.exists(get_image)判断,跳过不存在的图片避免运行中断。
内容的提问来源于stack exchange,提问作者ml_learner
相关产品推荐
相关产品推荐

