我有一个数据集,由130个文件夹组成,每个文件夹包含32张照片。
我想从每个文件夹中将照片(用于训练的26张照片,用于测试的3张照片以及用于验证的3张照片)随机复制到火车,验证和测试文件夹中的相应子文件夹(001、002、003 ...)。 所以我会有这样的东西:
火车套
- 001(文件夹包含26张照片)
- 002
- 003
- ....
验证集
- 001(文件夹包含3张照片)
- 002
- 003
- ....
火车套
- 001(文件夹包含3张照片)
- 002
- 003
- ....
这是代码:
import random
import shutil
n_photo_train = 26
n_photo_validation = 3
n_photo_test = 3
for idx in range(130):
source = '/Users/john/photodb_original/{d:03d}'.format(d=(idx + 1))
dest_train = '/Users/john/photodb_sets/Train/{d:03d}'.format(d=(idx + 1))
dest_validation = '/Users/john/photodb_sets/Validation/{d:03d}'.format(d=(idx + 1))
dest_test = '/Users/john/photodb_sets/Test/{d:03d}'.format(d=(idx + 1))
files = random.choice(os.listdir(source))
photo_train = files[:n_photo_train]
photo_test = files[26:29]
photo_val = files[29:]
shutil.copyfile(os.path.join(source, photo_train), dest_train)
shutil.copyfile(os.path.join(source, photo_val), dest_validation)
shutil.copyfile(os.path.join(source, photo_test), dest_test)
我收到此错误:IsADirectoryError: [Errno 21] Is a directory: '/Users/john/photodb_original/001/'
。
我是否使用了不正确的shutil.copyfile?否则,有没有办法以更紧凑和清晰的方式编写代码?
答案 0 :(得分:2)
random.choice(os.listdir(source))
将仅返回single element-当您尝试索引该字符串时,您将获得一个空字符串,而os.path.join
将返回目录路径-这将导致您的异常。
从您的代码看来,您打算使用random.shuffle
。请注意,如果您使用随机播放,它将使列表发生变化,因此您的代码应分为两个命令:
files = os.listdir(source)
random.shuffle(files)
答案 1 :(得分:1)
我认为您需要创建目录以在其中复制文件,或者在缺少目录缺失的异常时,请尝试先创建目录,然后再尝试复制文件。无论如何,这是我认为可以满足您需求的示例代码。
import os
from random import shuffle
from shutil import copyfile, rmtree
org = os.path.realpath('org')
trn = os.path.realpath('trn')
tst = os.path.realpath('tst')
val = os.path.realpath('val')
# How split will be performed 26 3 3
rnd = [trn]*26+[tst]*3+[val]*3
rmtree(trn)
rmtree(tst)
rmtree(val)
rmtree(org)
# CREATE DUMMY DATA
for i in range(1, 131):
d = os.path.join(org, "{:03d}".format(i))
os.makedirs(d, exist_ok=True)
for f in range(1, 33):
f = os.path.join(d, "{:02d}".format(f))
open(f, 'a').close()
# ACTUAL STUFF
for d in os.listdir(org):
os.makedirs(os.path.join(trn, d))
os.makedirs(os.path.join(tst, d))
os.makedirs(os.path.join(val, d))
files = os.listdir(os.path.join(org,d))
shuffle(rnd)
for f, trg in zip(os.listdir(os.path.join(org,d)),rnd):
scr = os.path.join(org,d,f)
dst = os.path.join(trg,d,f)
copyfile(scr,dst)