最近得到了一份带有班里所有学生身份证号的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']

最后生成的柱状图如下:

参考资料: python读取excel(xlrd) 最简单方式解决python matplotlib中文乱码问题