最近得到了一份带有班里所有学生身份证号的Excel文件,于是想要统计一下所有同学的出生信息。这里选用xlrd模块读取Excel文件,文件中三个工作表(Sheet)只有第一个有数据,所以读取第一个Sheet的内容。
data = xlrd.open_workbook('data.xls')
table = data.sheets()[0]
出生信息隐含在身份证号中,所以需要获取身份证号特定位数(7-14位)的信息。然后将姓名和六位出生日期建立一一对应关系,并保存到文件中。
col_id = 5 # 表中证件号码所在列
col_name = 2 # 表中姓名所在列
start = 6 # 身份证号截取开始序号
end = 14 # 身份证号截取结束序号
id_list = table.col_values(col_id)[1:] # 获取身份证号列表
bd_list = list(map(lambda x: x[start: end], id_list)) # 获取出生日期列表
name_list = table.col_values(col_name)[1:] # 获取姓名列表
d = dict(zip(name_list, bd_list)) # 将姓名和出生日期组合成字典
d_s = sorted(d.items(), key=lambda i: i[1]) # 字典按出生日期排序
jsObj = json.dumps(d_s, ensure_ascii=False) # 文件保存
with open('out.json', 'w', encoding='utf-8') as f:
f.write(jsObj)
为了让数据更加清晰,我使用出生年份制作了一张柱状图。x轴为所有的出生年份,y轴为各个出生年份的人数。
by_list = list(map(lambda x: x[: 4], bd_list)) # 依据出生日期列表获取出生年份列表
c = Counter(sorted(by_list)) # 用排序后的列表计数
x = list(c.keys())
y = list(c.values())
plt.bar(x, y) # 画柱状图
for a, b in zip(x, y): # 柱状图中标注数据
plt.text(a, b + 0.05, '%.0f' % b, ha='center', va='bottom', fontsize=11)
plt.xlabel('年份')
plt.ylabel('人数')
plt.title('2018届研究生生年统计')
plt.show()
需要注意的一点是,用于画图的matplotlib模块显示中文会出现乱码,Windows系统下可添加以下代码解决:
from pylab import mpl
mpl.rcParams['font.sans-serif'] = ['SimHei']
最后生成的柱状图如下: