栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

以2021年广东省新高考为例使部分高校投档分可视化

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

以2021年广东省新高考为例使部分高校投档分可视化

广东省和其它八个省份一起开始了他们的第一届新高考,这个改变其实是换汤不换药。总分还是750分,考试科目选择是“3+1+2”,是语文、数学、外语(注意不是英语,英语是外语之一)的3门必考科目、物理或历史的1门首选选择科目,政治、地理、生物、化学4门中选2门的再选选择科目组成的考试科目元组。本次的可视化以“1”对应的物理的选科区(即“物理类考生”)作为成绩分布样本。首先在互联网上找到广东省2021年普通高等学校招生全国统一考试物理类考生的“一分一段表”并将数据抽象成关系模式以便讲述。

上述关系模式中,G是成绩,Gr是真实成绩值,Q是人数,这个关系模式至少是第三范式,数据分析时出错的概率低。因为出错概率较低,所以不必要用C#.NET中的System.Linq进行二次筛选,直接上Python上进行数据分析。

import numpy
import matplotlib.pyplot

# make axises allow Chinese character to present
matplotlib.pyplot.rcParams['font.family'] = 'sans-serif'
matplotlib.pyplot.rcParams['font.sans-serif'] = 'SimHei'

上面是用到的库,numpy不用说了,可视化我利用的是pyplot模块。

表格文件有了,但是在怎么确定成绩和人数是服从什么分布的?在表格文件先画出散点图:

将这张图横坐标坐标500以后的值去掉,把y轴(人数轴)的值除以337988后会得很像正态分布的图。这些依据不能确定成绩服从正态分布,所以有必要从卡方分布和F分布入手去推测是否服从。考虑到卡方分布和F分布的最高点小的都有百分位,而现行的分数表格中最大的也只有千分位。所以正态分布较为合适。于是,对样本求平均数和方差的函数诞生了。

file = open(grade_file)
x_list = []
y_list = []
grade_list = []
for line in file:
    s = line.split(",")
    x_list.append(float(s[0]))
    y_list.append(float(s[1]))
    grade_list.append(float(s[2]))
average = 0
length = len(x_list)
y_sum = sum(y_list)
for i in range(0, length):
    average += x_list[i] * y_list[i] / y_sum
real_average = grade_list[0] - average
difference = 0
for i in x_list:
    difference += (i - average) ** 2 / length
error = 0
for i in range(0, length):
    error += (y_list[i] / y_sum - numpy.exp(-(x_list[i] - average) ** 2 / (2 * difference)) / (numpy.sqrt(2 * numpy.pi * difference))) ** 2
file.close()

这里有一个real_average和average的变量,前者指的是分数的平均值,后者指的是对文件进行读取时取得的平均值。grade_list[0]指最高分。封装之。

def analysing_grade(grade_file):
    file = open(grade_file, encoding="utf-8")
    x_list = []
    y_list = []
    grade_list = []
    for line in file:
        s = line.split(",")
        x_list.append(float(s[0]))
        y_list.append(float(s[1]))
        grade_list.append(float(s[2]))
    average = 0
    length = len(x_list)
    y_sum = sum(y_list)
    for i in range(0, length):
        average += x_list[i] * y_list[i] / y_sum
    real_average = grade_list[0] - average
    difference = 0
    for i in x_list:
        difference += (i - average) ** 2 / length
    error = 0
    for i in range(0, length):
        error += (y_list[i] / y_sum - numpy.exp(-(x_list[i] - average) ** 2 / (2 * difference)) / (numpy.sqrt(2 * numpy.pi * difference))) ** 2
    file.close()
    return real_average, difference, error, y_sum, x_list, y_list, grade_list

最后得到的结果是:

我们可以看到广东一点都不卷,说实话,本人在珠三角高考的一点都有点不相信这个数据,但是用了正态分布去套还是得接受。言归正传,得到了数据后我们就要着手写第二个函数了,数据需求那就是2021年在广东省招生的高校的投档分(最低分)对应物理类的表格即可。本人在互联网上找到并转成表格,因为2021年广东省进行投档招生的专业都叫“专业组”,所以一个学校有几个甚至十几个专业组的比比皆是。如:吉林大学今年在广东招生的时设置了12个专业组,苏州大学设置了9个专业组。对这些专业组、招生人数、对应最低分,本人第二次利用加权平均值算吉林大学对应的分数是612分,苏州大学是607分。对这些平均值本人重新做了一个表格,并且根据关系实例抽象出关系模式。

在这个关系模式中,前者是高校,后者是对各专业组的分数按照人数加权平均得到的量。原表的关系范式是第二范式,对于它的处理需要栈和查询——难点在这里,所以本人先将专业组的分数进行加权,然后重新制作了投档情况表格。并且对表格的组织结构设置函数,上代码:

def plot_normal_distribution_with_school(average, difference, school_file, initial_person_list, initial_grade_list):
    matplotlib.pyplot.figure(figsize=(32, 24), )
    x = numpy.arange(550, 700, 10 ** (-2))

    # set border
    border = matplotlib.pyplot.gca()
    border.spines['right'].set_color('none')
    border.spines['top'].set_color('none')

    # plot
    matplotlib.pyplot.xlim(550, 700)
    matplotlib.pyplot.ylim(0.001, 0.0019)
    matplotlib.pyplot.plot(x,numpy.exp(-(x - average) ** 2 / (2 * difference)) / (numpy.sqrt(2 * numpy.pi * difference)),
                           linewidth=1.5, label='$f(x)=N({},{})$'.format(average, difference))
    matplotlib.pyplot.xlabel('x', fontsize=24)
    matplotlib.pyplot.ylabel('y', fontsize=24)
    matplotlib.pyplot.legend(prop={'size': 24})

    # school and grade file dealing
    school = open(school_file)
    school_list = []
    grade_list = []
    for line in school:
        ls = line.split(",")
        school_list.append(ls[0])
        grade_list.append(int(ls[1]))

    # mark up every school and ranks
    matplotlib.pyplot.xticks(grade_list, school_list, rotation=270)
    grade_probability_list = []
    person_probability_list = []
    for item in grade_list:
        grade_probability_list.append(numpy.exp(-(item - average) ** 2 / (2 * difference)) / (numpy.sqrt(2 * numpy.pi * difference)))
        for i in range(0, len(initial_grade_list)):
            if initial_grade_list[i] == item:
                person_probability_list.append(sum(initial_person_list[:i]))
                break
    matplotlib.pyplot.yticks(grade_probability_list, person_probability_list)

    # plot lines and show
    for i in range(0, len(grade_probability_list)):
        matplotlib.pyplot.plot([grade_list[i], grade_list[i]], [0, grade_probability_list[i]], '*-')
        matplotlib.pyplot.plot([0, grade_list[i]], [grade_probability_list[i], grade_probability_list[i]], '*-')
    matplotlib.pyplot.show()

诸位也从函数中看出来了本人是在掐尖(在第三行),对这两个函数加以运行的时候是这样的:

tuple_list = []
tuple1 = analysing_grade("test_guangdong2021.csv")
plot_normal_distribution_with_school(tuple1[0], tuple1[1], "accept_guangdong_2021.csv", tuple1[3],tuple1[4], tuple1[5], tuple1[6])

最后运行的图是这样的(图片的长和宽是3200和2400):

 图上显示的x轴,颜色越深说明越多的高校(四五所也是有可能的)大致在这个分数招生。还有一张图:

这张图的目的就是说明广东还是卷的。

如果有时间,本人可以再搜集一下资料做多几个省份的图,也算看看怎么投成这种情况的。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/286137.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号