我的第一个python程序——mnist读取和展示
第一次使用python,适应了C和C++的严谨,再用python,感觉很不适应。随着编程的继续,渐渐发现python的随意只是表象,那只是给老鸟减少麻烦用的。
我的第一个python程序是mnist数据集的读取。这个没什么难度,函数是从网上抄的。对我来说难点是matplotlib。这个东西很好用,但那是在仔细阅读文档之后。写这个东西的目的,就是给matplotlib的初学者参考吧。
代码
import struct
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.widgets import Slider, Button
def decode_idx3_ubyte(idx3_ubyte_file):
with open(idx3_ubyte_file, 'rb') as f:
print('解析文件:', idx3_ubyte_file)
fb_data = f.read()
offset = 0
fmt_header = '>iiii' # 以大端法读取4个 unsinged int32
magic_number, num_images, num_rows, num_cols = struct.unpack_from(fmt_header, fb_data, offset)
print('idex3 魔数:{},图片数:{}'.format(magic_number, num_images))
offset += struct.calcsize(fmt_header)
fmt_image = '>' + str(num_rows * num_cols) + 'B'
images = np.empty((num_images, num_rows, num_cols))
for i in range(num_images):
im = struct.unpack_from(fmt_image, fb_data, offset)
images[i] = np.array(im).reshape((num_rows, num_cols))
offset += struct.calcsize(fmt_image)
return images
def decode_idx1_ubyte(idx1_ubyte_file):
with open(idx1_ubyte_file, 'rb') as f:
print('解析文件:', idx1_ubyte_file)
fb_data = f.read()
offset = 0
fmt_header = '>ii' # 以大端法读取两个 unsinged int32
magic_number, label_num = struct.unpack_from(fmt_header, fb_data, offset)
print('idex1 魔数:{},标签数:{}'.format(magic_number, label_num))
offset += struct.calcsize(fmt_header)
labels = []
fmt_label = '>B' # 每次读取一个 byte
for i in range(label_num):
labels.append(struct.unpack_from(fmt_label, fb_data, offset)[0])
offset += struct.calcsize(fmt_label)
return labels
img=decode_idx3_ubyte("/home/zhangyl/Downloads/mnist/train-images.idx3-ubyte")
result=decode_idx1_ubyte("/home/zhangyl/Downloads/mnist/train-labels.idx1-ubyte")
fig, ax = plt.subplots(nrows=6, ncols=5, sharex='all', sharey='all')
plt.subplots_adjust(right=2.5) #调整宽度让页码能够显示出来
ax_control=plt.subplot(6,1,5)
ax_button_start=plt.subplot(6,5,26)
ax_button_previous=plt.subplot(6,5,27)
ax_button_next=plt.subplot(6,5,29)
ax_button_end=plt.subplot(6,5,30)
#把button中间的方框去掉。plt.tight_layout()要求subplot布局必须是整数倍,不能一行四个,一行五个
ax_button_pad=plt.subplot(6,5,28)
ax_button_pad.spines['top'].set_visible(False)
ax_button_pad.spines['bottom'].set_visible(False)
ax_button_pad.spines['left'].set_visible(False)
ax_button_pad.spines['right'].set_visible(False)
ax_button_pad.set_xticks([])
ax_button_pad.set_yticks([])
fig.canvas.toolbar.hide()
start_f=0.0
ax = ax.flatten()
def draw_page(page_number):
im_start=page_number*20
for i in range(20):
ax[i].imshow(img[i+im_start],cmap='Greys', interpolation='nearest')
n=result[i+im_start]
ax[i].set_title(str(n))
page=0
draw_page(page)
ax[0].set_xticks([])
ax[0].set_yticks([])
axcolor = 'lightgoldenrodyellow'
myslider= Slider(ax_control, 'Page', 0.0, 2999, valinit=0.0, valstep=1.0,valfmt="%d")
button_start = Button(ax_button_start, 'Start', color=axcolor, hovercolor='0.975')
button_end = Button(ax_button_end, 'End', color=axcolor, hovercolor='0.975')
button_previous = Button(ax_button_previous, 'Prev', color=axcolor, hovercolor='0.975')
button_next = Button(ax_button_next, 'Next', color=axcolor, hovercolor='0.975')
def on_slider_update(val):
global page
page=int(myslider.val)
draw_page(page)
fig.canvas.draw_idle()
myslider.on_changed(on_slider_update)
def on_button_start(event):
global page
page=0
draw_page(page)
myslider.set_val(0)
fig.canvas.draw_idle()
def on_button_end(vent):
global page
page=2999
draw_page(page)
myslider.set_val(2999)
fig.canvas.draw_idle()
def on_button_previous(event):
global page
if page!=0:
page=page-1
draw_page(page)
myslider.set_val(page)
fig.canvas.draw_idle()
def on_button_next(event):
global page
if page!=2999:
page=page+1
draw_page(page)
myslider.set_val(page)
fig.canvas.draw_idle()
button_start.on_clicked(on_button_start)
button_end.on_clicked(on_button_end)
button_previous.on_clicked(on_button_previous)
button_next.on_clicked(on_button_next)
plt.tight_layout()
plt.show()