机器学习是计算机对大量数据的分析过程,在机器学习的实际项目中,通常都需要准备数据集,数据集通常包含的数据数量是庞大的。例如,在处理计算机视觉领域的项目时,每一张图片都是一个单独的文件,为了提高模型训练的效果,图片数量通常会比较多,因此需要合理且高效的操作将所有的图片数据读取。本篇旨在介绍如何用Python对海量文件进行遍历,也是机器学习实践的第一步。
数据准备
为了模拟海量文件,需要准备一个包含大规模文件的数据包,也就是用来参与模型训练的数据集。假设在当前计算机系统(文章使用Linux操作系统,其他操作系统同理)中,根目录下有我们需要的数据集data,用tree命令递归地以树状格式列出或显示目录的内容。它输出每个子目录中的目录路径和文件,以及子目录和文件总数的摘要。
tree -L 3 ./data/
./data/
└── data10954
├── cat_12_test.zip
├── cat_12_train.zip
└── train_list.txt
1 directory, 3 files
可以发现引用的数据集为zip压缩格式,因此必须先解压到当前的工作空间后才能读取里面的数据,目前各种公开的数据集基本上都是以压缩包的形式出现在网络中。下面介绍直接用Python解压数据包的方法。这里定义了解压函数unzip_data(src_path, tar_path),参数为待解压文件与将要解压到的文件夹名称,在之后直接调用定义好的解压函数就可以把两个数据集解压。
import zipfile
import os
def unzip_data(src_path,target_path):
# 解压原始数据集,将src_path路径下的zip包解压至target_path目录下
if(not os.path.isdir(target_path)):
z = zipfile.ZipFile(src_path, 'r')
z.extractall(path=target_path)
z.close()
unzip_data('data/data10954/cat_12_test.zip','data/data10954/cat_12_test')
unzip_data('data/data10954/cat_12_train.zip','data/data10954/cat_12_train')
tree -L 2 ./data/
./data/
└── data10954
├── cat_12_test
├── cat_12_test.zip
├── cat_12_train
├── cat_12_train.zip
└── train_list.txt
3 directories, 3 files
实现文件的类型与存储空间的统计
上一步已经准备好了图片数据集,这里介绍用Python实现通过给定目录统计所有不同子文件类型及占用存储空间大小的方法。
os.path.join() 将参数拼接为路径格式
os.path.isdir() 判断一个路径是否为文件夹
os.path.isfile() 判断一个路径是否为文件
os.path.splitext() 获取文件后缀
os.path.getsize() 返回路径占用空间大小
import os
"""
通过给定目录,统计所有的不同子文件类型及占用内存
"""
size_dict = {}
type_dict = {}
def get_size_type(path):
files = os.listdir(path)
for filename in files:
temp_path = os.path.join(path, filename)
if os.path.isdir(temp_path):
# 递归调用函数,实现深度文件名解析
get_size_type(temp_path)
elif os.path.isfile(temp_path):
# 获取文件后缀
type_name=os.path.splitext(temp_path)[1]
#无后缀名的文件
if not type_name:
type_dict.setdefault("None", 0)
type_dict["None"] += 1
size_dict.setdefault("None", 0)
size_dict["None"] += os.path.getsize(temp_path)
# 有后缀的文件
else:
type_dict.setdefault(type_name, 0)
type_dict[type_name] += 1
size_dict.setdefault(type_name, 0)
# 获取文件大小
size_dict[type_name] += os.path.getsize(temp_path)
path= "data/"
get_size_type(path)
for each_type in type_dict.keys():
print ("%5s下共有【%5s】的文件【%5d】个,占用内存【%7.2f】MB" %
(path,each_type,type_dict[each_type],\
size_dict[each_type]/(1024*1024)))
print("总文件数: 【%d】"%(sum(type_dict.values())))
print("总内存大小:【%.2f】GB"%(sum(size_dict.values())/(1024**3)))
输出如下:
data/下共有【 .txt】的文件【 1】个,占用内存【 0.11】MB
data/下共有【 .zip】的文件【 2】个,占用内存【 205.80】MB
data/下共有【 .jpg】的文件【 2400】个,占用内存【 207.66】MB
总文件数: 【2403】
总内存大小:【0.40】GB