本篇文章使用 pandas 和 matplotlib 对广州大学方滨兴院士班2019年调剂群里的成员信息进行了分析, 大家可以在文末的数据图表中很直观地看出985/211学生占比、有调剂意愿的生源主要来自哪些学校、哪些专业等信息. 同时希望本文中应用的分析手段和技巧可以给大家提供一些新的思路. 如果你对我最终整理的数据感兴趣, 也可以联系我, 我会发送给你.
本篇文章主要分为三个部分:
- 数据获取
- 数据清洗
- 数据分析
一、数据获取
数据获取即获取群成员的 raw data 是一个很棘手的问题, 因为百度和谷歌上的搜索结果, 都是针对 web QQ ( Smart QQ) 来写的, 而 web QQ 已经从2019年1月1日起停止服务了, 也就是说, 那些方法都失效了.
另一种广为流传的方法是: 在 qq 群网页版的成员管理里来爬取, 然而很遗憾, 这种方法也已被腾讯封停了(现在https://qun.qq.com的成员管理页面是空白的)
而通过必应搜索(http://bing.com)可以发现一种通过qq邮箱的"订阅空间"功能来获取群成员的方法, 这种方法比较hack, 你可以在选择订阅对象的时候看到整个群里所有成员的信息, 然后你直接把这些信息复制到excel里即可
二、数据清洗
这部分是最脏最累的地方, 没什么技术含量, 还特别耽误时间.
上面得到的是一大堆数据, 挤在 excel 的一列里, 你需要使用 excel 的分列功能, 按不同的分隔符将其拆开.
令人头痛的是, 群里的许多人并没有按照群公告的格式来填写, 于是你需要对那些垃圾数据进行处理, 在这里提供一个可以节约一定时间的思路 —— 善用排序
分列之后对数据进行排序, 可以让一些不符合格式的垃圾数据浮到头部, 于是你只需要再对头部的数据进行处理即可, 通过不断的对其进行处理, 最终可以得到一个相对比较格式化的 excel数据表格
在这部分中, 我删掉了一些信息不全的条目, 因为他们既然信息都没有填写完全, 那可能就是对这个调剂并不是很在意, 其对最终的录取结果应该影响不大, 这部分数据大概有200条左右.
同样, 判断该同学本科学校是否为 985/211, 也是通过对学校一列进行排序, 然后通过python来识别( 将211/985大学全称存入两个数组中, 再用 python 的 if in 语句来判断.), 但是有些人会填自己学校的简称(南大? 南京大学? 南开大学? 河大? 河北大学? 河南大学?). 没有选择用正则来匹配, 而是手动补全剩余部分.
可以看出, 这部分很多问题都是来自群昵称格式不规范, 我是真的很想扔掉这些数据, 但是为了最终结果具有代表性, 还是强忍头痛把这部分数据补完了.
格式化数据三、数据分析
终于到了最激动人心的数据分析部分, 现在我们得到了完全格式化的数据了.
import pandas as pd
import matplotlib.pyplot as plt
import matplotlib as mpl
# 解决 matplotlib 中文乱码问题
mpl.rcParams[u'font.sans-serif'] = ['simhei']
mpl.rcParams['axes.unicode_minus'] = False
# 读数据
df = pd.DataFrame(pd.read_excel('data.xlsx', names=['姓名', '学校', '是否211', '是否985', '专业', '应往届']))
首先我们来看一下大家都来自什么学校:
# 各学校人数
college_count = df['学校'].value_counts()[:10]
x = college_count.index
y = college_count
plt.bar(x, y, align='center')
plt.title('Top10大学及人数')
for a, b in zip(x, y):
plt.text(a, b+0.05, '%.0f' % b, ha='center', va='bottom', fontsize=11)
plt.show()
(这里顺便提一下, 取前10行数据, 我写[:10]并没有写错, 这是 pandas 和 原生python 的一个小区别)
然后我们看下 211大学在其生源中所占的比例:
# 绘制 211 饼图
is_211 = df['是否211'].fillna('双非')
is_211 = is_211.value_counts()
explode = (0, 0.1, 0)
fig1, ax1 = plt.subplots()
ax1.pie(is_211, explode=explode, labels=is_211.index, autopct='%1.1f%%',
shadow=True, startangle=90)
ax1.axis('equal')
plt.show()
接下来, 我们来看一下 985 生源所占比例:
# 绘制 985 饼图
is_985 = df['是否985'].fillna('非985')
is_985 = is_985.value_counts()
explode = (0, 0.1)
fig1, ax1 = plt.subplots()
ax1.pie(is_985, explode=explode, labels=is_985.index, autopct='%1.1f%%',
shadow=True, startangle=90)
ax1.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
plt.show()
然后是大家主要来自什么专业:
Top10专业及人数
Top10专业及人数
可以看出, 虽然方班不限制专业, 但是大家主要还是计算机及软工专业, 而在top20里, 则多了机械和自动化专业.
# 专业条形图
major_count = df['专业'].value_counts()[:10]
x = major_count.index
y = major_count
plt.bar(x, y, align='center')
plt.title('Top10专业及人数')
for a, b in zip(major_count.index, major_count):
plt.text(a, b+0.05, '%.0f' % b, ha='center', va='bottom', fontsize=11)
plt.show()
最后我们来看下应届/往届生源比例:
# 绘制应往届生饼图
fresh_grad = df['应往届'].fillna('未知')
fresh_grad = fresh_grad[fresh_grad.isin(['应届', '往届', '未知'])]
fresh_grad_count = fresh_grad.value_counts()
explode = (0, 0.1, 0)
fig1, ax1 = plt.subplots()
ax1.pie(fresh_grad_count, explode=explode, labels=fresh_grad_count.index, autopct='%1.1f%%',
shadow=True, startangle=90)
ax1.axis('equal') # Equal aspect ratio ensures that pie is drawn as a circle.
plt.show()
网友评论