起头
突发奇想, 想看下高考成就的散布, 若是把每个省市的成就划线成0-100 分会怎么样,简单的来说, 认为更高分的考了100分,更低分考了0分, 计算一下各个分数段的人数就好了,
趁便能够用那个数据看每个省市的一本线划分比率,还有其他相关的数据,
看起来仍是比力简单的, 脱手尝尝
数据搜集网上找了一下, 每年的高考人数, 如今已经超越万万人高考了,河南更是超越了100万, 数据来源:新浪教育 https://edu.sina.cn/zt_d/gkbm
那个表的数据是统计的全国各个省市(除港澳台)之外的数据, 各个省市在出成就之后会出各自的一分一段表, 统计每一分的成就的人数, 我们以那个数据为准, 因为小我仍是没有太多精神去搜集数据的,网上找到了 高考100-一分一段表 那个网站, 给出了各个省市的一分一段表, excel 版本, 略微查抄了一下, 数据应该是对的,我就暂时以那个数据为准,
数据太多, 我暂时只做 35万 以上人的省市,只要11个省市,加上 北京上海两个城市的数据, - 河南 - 河北 - 广东 - 广西 - 湖南 - 湖北 - 江西 - 贵州 - 安徽 - 四川 - 山东 - 北京 - 上海
此中北京上海不分科,山东是选择一门测验停止查核, 所以 一共23个数据表,后续的话,我尽量将数据也一并上传了
数据整理上面也提到了北京上海山东的分科比力特殊, 我们就按文理一路算,每个省都是给出更高分及以上的数据, 然后给出100分及以下的数据,但是不是每个省都是100分以下,所以还要特殊考虑,
差别高考政策与分类山东的高考政策详细不清晰, 但是似乎是考生是在6门副科中任选3门,从一图领会山东高考变革要点 那里查到的
我们就不做分科了, 间接看山东的全体成就即可。
差别统计体例北京的人数更少,在400分以下每10分段给出人数,我们为了便于便利 默认每个分数均匀人数, 好比 390-399分段的人有813人,我们认为每个分段都有81.3人,暂时那么处置。
差别省市关于更高分数的暗示都是 更高分数及以上, 但是关于更低分数的处置就不太一样了, 那里不做评价 好比良多省市是合并在一路 100分以下总计, 有些则只是100分的成就, 100分以下的成就是没有给出的,那里最初处置的时候, 我们把0分的人都删除了, 只计算1-100 的人,归正不影响整个曲线
最末我们整理得到数据表, 每个Sheet 暗示一个省市的文理科目,然后最上面一行数据别离对应 总分,人数, 累计人数,
数据处置 数据处置思绪那里为了便利 随手用 Python 来做的, 利用的 pandas 读取的 excel 文件, 我们统计所有的数据的目的就是 将成就化为 0-100分 那么
变更后分数 = \frac{当前分数-更低分}{更高分-更低分} \times 100
关于每个省的成就将其调整到 [0,100], 那里利用的是 四舍五入, 招致现实在计算过程中的数据会堆叠,好比相邻的两个成就一个舍去,一个入上,在同一分数,招致数据噪声较大, 那是利用 一维的中值滤波光滑一下数据就好了,
以河南文科为例, 我们间接绘造归一化之后的成就并停止中值滤波之后比照, (图为测试过程中归一化到500分的图像,不影响理解)
各省市分数散布我们在之前已经整理得到的数据, 然后我们 就要脱手做了,
# 整理数据,将各省市的成就归一到100分之后的散布比率 # 引入 pandas import pandas as pd import matplotlib import matplotlib.pyplot as plt import scipy.signal as ss # 设定中文字体 plt.rcParams[font.sans-serif]=[SimHei] #用来一般显示中文标签 plt.rcParams[axes.unicode_minus]=False #用来一般显示负号 # 设定图像尺寸 与分辩率 plt.rcParams[figure.figsize] = (8.0, 4.0) # 设置figure_size尺寸 plt.rcParams[image.interpolation] = nearest # 设置 interpolation style plt.rcParams[savefig.dpi] = 300 #图片像素 plt.rcParams[figure.dpi] = 300 #分辩率 # 将成就同一到 [0,] 区间 MAX_SCORE = 100 MIN_SCORE = 0 data_file = Data/data.xlsx res_file = Data/res-+str(MAX_SCORE-MIN_SCORE)+.xlsx # 读取excel , 获取所有表单名字 excel_info = pd.ExcelFile(data_file) all_data = {} all_data_ratio = {} # 获取表中的每一个数据文件 并将数据归一化到 0-500 for index in range(len(excel_info.sheet_names)): # 读取每一个表单 cur_sheetname = excel_info.sheet_names[index] df_sheet = pd.read_excel(data_file, sheet_name=cur_sheetname) # 获取每一个表中的 总分数 和对应分数的人数 scores = df_sheet[df_sheet.columns.values[0]] nums = df_sheet[df_sheet.columns.values[1]] # 数据 对应 每个分数的人数 表 ROWS = MAX_SCORE - MIN_SCORE + 1 trans_scores_nums = [0] * ROWS rows = len(scores) cur_max_score = scores[0] cur_min_score = scores[rows - 1] cur_index = 0; for s in scores: # 计算 变更之后的分数 四舍五入 trans_score = (int)(round((s - cur_min_score) / (cur_max_score - cur_min_score) * (MAX_SCORE - MIN_SCORE))) # 在计算分数的位置上 加上对应分数的人数 trans_scores_nums[trans_score - 1] += nums[cur_index]; cur_index += 1 # 数据略微处置一下, 做简单的光滑处置, 去除更低分数据 except0data = [0] * (ROWS - 1) for i in range(ROWS - 1): except0data[i] = trans_scores_nums[i + 1]; # 中值滤波去除噪点 smooth_trans = ss.medfilt(except0data, 7) # 将数据转换成比例, 更具有一般性 sum = 0 smooth_trans_ratio = [0] * (ROWS - 1) for i in range(ROWS - 1): sum += smooth_trans[i] for i in range(ROWS - 1): smooth_trans_ratio[i] = smooth_trans[i] / sum all_data[cur_sheetname] = smooth_trans all_data_ratio[cur_sheetname] = smooth_trans_ratio print(正在停止 {0}/{1}, 表名:{2}.format(index + 1, len(excel_info.sheet_names), cur_sheetname)) # plt.plot(smooth_trans2) # write_data = pd.DataFrame(all_data) # write_data.to_excel(res_file,sheet_name=res) write_data_ratio = pd.DataFrame(all_data_ratio) write_data_ratio.to_excel(res_file, sheet_name=ratio) print(已经完成,存储文件:{0}.format(res_file))我们在那个法式里面次要是 将数据提取出来, 计算成 100分造之后,从头存入 excel 表中,此中人数部门换成了各省市的人数比率,也便利查阅后续的数据 ( 因为我觉得 plt 绘造图像欠好看,那边利用了MATLAB 停止图像的绘造过程)
% 将 原始数据绘造出来 并计算均匀值和中值 % 读取 excel 数据 获取名称以及各列名称 data_file = Data/res-100.xlsx; res_ratio = xlsread(data_file,1,B2:X501); res_name = {河南文科, 河南理科, 北京, 上海, 河北文科, 河北理科, 山东, 广东文科 广东理科 湖北文科, 湖北理科, 湖南文科, 湖南理科, 四川文科, 四川理科, 安徽文科, 安徽理科, 广西文科, 广西理科, 贵州文科, 贵州理科, 江西文科, 江西理科}; figure() hold on [rows,cols] = size(res_ratio); avg = zeros(cols,1); media =zeros(cols,1); for i=1:cols % 绘造百分比率图 plot(res_ratio(:,i)*100); % 计算均匀值 中值 media_l = 0.5; media_find_flg = 0; for j = 1:rows avg(i) = avg(i) + j*res_ratio(j,i); % 统计比率超越一半的 数之后就是中值 找到后就不更新了 if(media_find_flg ==0) if(media_l >0) media_l = media_l - res_ratio(j,i); else media(i) = j; media_find_flg = 1; end end end end legend(res_name); % 创建 xlabel xlabel({归一化到100分后成就}); % 创建 title title({各省市归一化成就散布比率}); % 创建 ylabel ylabel({单元成就散布比率});最末我们得到了如许的一副图, 细节部门比力多,且数据噪声较大,但是数据的整体趋向大要大白了,噪声较大的黄色的线是北京的,暂时不做过多阐发
各省市分数均匀值与中值我们那里的计算均匀值就是 每分段人数乘以该分段的比例,最末得到的成果, 然后, 中值那里简单除暴, 找到中间比率所在的区间就好了, 代码没有去过多处置, 能跑出来成果就好
数据简单阐发我们在上一章节给出了一张图, matlab 绘造的图的颜色比力接近, 建议下载原图旁观,给出了散布图, 我们把数据最为特殊的几条线零丁绘造一下,
最偏右的 黄色 北京最偏左的 紫色 广西文科更高的 浅蓝色 贵州文科最均匀的 浅紫色 湖北理科双峰的 蓝色 江西文科其实那些形态是有奇特的意义的,理论上的曲线是正太散布的,但是因为各类原因,我们以现实曲线为主, - 靠右暗示 数据整体偏大 - 靠左整体偏小 - 更高的暗示数据比力集中, - 更低的暗示数据散布平均 - 双峰的暗示数据割裂严峻(我瞎编的)。。。
就总体而言, 各个省市的成就的峰值(寡数)也主页也分为两个部门,部门省市的峰值在40分摆布,次要包罗河南文科,河北文科,湖北文科,广西文科,广西理科 剩下的分数的寡数都集中在60分多一点的位置,
emmm, 就那么多了, 再多的阐发也没有太多用, 究竟结果北京NB
剩下的部门就是 高考本科上线率那种数据了, 但是各省关于本科的分数线实是差别
我给出的数据是我在各地高考历年分数线(批次线) 那个网页上能看到2020 年各省高考批次线, 一般的省市都是划分 1本2本专科, 除了北京,上海,河北,山东,广东 后面想法子再做吧, 估量会不做了
高考大省与高考小省我们拿高考大省河南河北然后比照上海和北京, 看下数据 其实那里应该去找数据轴上的最明显特征的线, 详细数据本身阐发好了
但是我们暂时只看那几个数据,
都是前面给出的数据, 我们绘造出来了
北京的成就是明显优于河北的,河南和上海的数据其实是不断的,即便是在全数曲线图上也算比力中间的类型了,
总结搞了半天, 屁用没有,就是手痒然后就搞了一大堆, 越搞越多, 后续还有一堆要做的,
按照本篇数据而言, 北京的成就是比全国各个省市的成就要好的,可能与培育体例差别吧,
其实那种分数散布其实不必然是培育形成的, 还有部门是各省测验情况差别招致的,所以数据仅供参考, 北京NB
备注我将所有的数据都存在了 Github 上
https://github.com/SChen1024/GaoKao
有兴趣的可随意拿数据停止阐发, 后续还会做完最初一点
PS:第一次在知乎发文章 后台实的一言难尽, markdown 功用是废的一样,