struct module
最近在学CNN,想找一个合适的数据集,就想到了MINST。但是官网中挂出的文件是train-images-idx3-ubyte.gz等解压后为idx3-ubyte后缀文件。后缀名中idx3表示3维的数据。
简介
struct模块用于二进制和常用数据类型之间的互相转化,此模块中大部分函数接受一个实现了Buffer协议的对象,最常见的实现了Buffer协议的对象包括bytes、bytearray等,大多数像byte数组这样的对象都实现了Buffer协议。
常用函数
简单来说buffer是字节流,format是格式。pack和pack_into将python中数据类型转换为二进制文件;unpack和unpack_from将二进制文件转换成所需的数据格式。
- struct.pack(format, …)
- 将多个变量按照format的格式格式化
- struct.pack_into(format, buffer, offset, …)
- 将多个变量按照format格式格式化到buffer的offset处
- struct.unpack(format, buffer)
- 从buffer中按照format格式解析对象
- struct.unpack_from(format, buffer, offset=0)
- 从buffer的offset处解析对象
- struct.iter_unpack(format, buffer)
- 以迭代的形式从buffer中解析对象
- struct.calcsize(format)
- 返回format所指定的数据类型的字节数
常见format
格式 | python中数据类型 | 字节数 |
---|---|---|
i或I | integer | 4 |
b或B | integer | 1 |
h或H | integer | 2 |
s | string | 1 |
d | double | 8 |
解析MINST
直接上代码
import struct
import matplotlib.pyplot as plt
import numpy as np
# 文件结构
# [offset] [type] [value] [description]
# 0000 32 bit integer 0x00000803(2051) magic number # 用于确认文件没有损坏
# 0004 32 bit integer 60000 number of images
# 0008 32 bit integer 28 number of rows
# 0012 32 bit integer 28 number of columns
# 0016 unsigned byte ?? pixel
# 0017 unsigned byte ?? pixel
# ........
# xxxx unsigned byte ?? pixel
filename = r'D:\VS-Code-python\dataset\train-images.idx3-ubyte'
if __name__ == '__main__':
# open file
binfile = open(filename, 'rb')
print(binfile)
# read bin file
buf = binfile.read()
print(buf)
# magic_number,num_images,num_rows,num_cols
index = 0
magic_number,num_images,num_rows,num_cols = struct.unpack_from('>iiii', buf, index)
print(magic_number, num_images, num_rows, num_cols)
index += struct.calcsize('>IIII')
for i in range(100):
# 创建子图
plt.subplot(10,10,i+1)
# 读取784个unsigned byte,相当于读取一张图
im = struct.unpack_from('>784B', buf, index)
index += struct.calcsize('>784B')
# 读取的是列表,转换成array后,reshape成28*28的图像
im = np.array(im)
im = im.reshape(28, 28)
# 隐藏坐标轴
plt.xticks([])
plt.yticks([])
# 绘图
plt.imshow(im, cmap='gray')
plt.show()
结果如下
#binfile
<_io.BufferedReader name='D:\\VS-Code-python\\dataset\\train-images.idx3-ubyte'>
#buf
b'\x00\x00\x08\x03\x00\x00\...'(这里不展开了)
# magic_number,num_images,num_rows,num_cols
2051 60000 28 28