random.sample划分COVID-19数据集报Sample larger than population错误修复
错误原因
- 核心触发逻辑:Python标准库
random.sample(population, k)的参数约束为采样数k必须满足0 ≤ k ≤ 待采样序列总长度,违反该约束就会抛出你看到的Sample larger than population or is negative错误。触发该问题通常有两种情况:一是COVID-19 Radiography Dataset中部分类别(如Viral Pneumonia)的初始图片总量不足你设定的30张采样值;二是你之前已经运行过一次划分代码,已经从原类别目录移动了部分图片到测试集,再次运行时原目录剩余的PNG图片数量小于30,采样时直接报错。 - 附带隐藏bug:代码中测试集目录名前后不一致,前期创建的是
test2目录及对应类别子文件夹,后续移动文件时目标路径却写为test目录,即使解决采样报错,后续执行移动操作时也会因目标路径不存在触发文件找不到错误。
修复方案
按以下几点调整代码即可正常完成数据集划分:
- 采样时动态取「预设单类测试集样本数」和「当前类别实际有效图片总数」的较小值,避免采样数超过类别总样本量;
- 统一测试集目录命名,前后路径保持一致;
- 增加目录存在性判断,避免重复运行代码时因目录已存在抛出创建错误。
修正后的可运行代码如下:
import os import random import shutil class_names = ['Normal', 'Viral Pneumonia', 'COVID','Lung_Opacity'] root_dir = 'COVID-19_Radiography_Dataset' source_dirs = ['Normal', 'Viral Pneumonia', 'COVID','Lung_Opacity'] test_dir = os.path.join(root_dir, 'test') # 统一测试集目录名 sample_per_class = 30 # 单类测试集采样数,可根据需求调整 if os.path.isdir(os.path.join(root_dir, source_dirs[1])): # 测试集根目录不存在时再创建 if not os.path.isdir(test_dir): os.mkdir(test_dir) # 统一类别目录名 for i, d in enumerate(source_dirs): target_class_dir = os.path.join(root_dir, class_names[i]) if not os.path.isdir(target_class_dir): os.rename(os.path.join(root_dir, d), target_class_dir) # 创建测试集下的类别子目录 for c in class_names: class_test_dir = os.path.join(test_dir, c) if not os.path.isdir(class_test_dir): os.mkdir(class_test_dir) # 逐类采样移动 for c in class_names: class_train_dir = os.path.join(root_dir, c) images = [x for x in os.listdir(class_train_dir) if x.lower().endswith('png')] # 动态计算实际采样数,不超过当前类别图片总量 actual_sample_num = min(sample_per_class, len(images)) selected_images = random.sample(images, actual_sample_num) for image in selected_images: source_path = os.path.join(class_train_dir, image) target_path = os.path.join(test_dir, c, image) shutil.move(source_path, target_path)
补充说明:如果需要按比例划分训练/测试集(比如每个类取20%样本作为测试集),可以把
actual_sample_num的计算逻辑替换为int(len(images) * test_ratio)即可,适配不同类别样本量不均衡的场景。
内容的提问来源于stack exchange,提问作者user19292411
相关产品推荐
相关产品推荐

