Pandas自带了一个描述性统计函数:describ(),用来描述'计数','均值','标准差','最小值','25%','50%','75%','最大值',统计数据比较基础,可以用来作对比,并画图,代码如下:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
tablePath = '1数据清洗后成绩.xlsx'
classTimeList = ['化学1','化学2','化学3','化学4','化学5','化学6']
noteType = '教法'
dataShowList = [] #存储成对的数据,A、B系列的data
# 导入测试的xls数据,并DataFrame化
originalData = pd.DataFrame(pd.read_excel(tablePath)) # 导入excel数据,并转化为DataFrame格式
for i in classTimeList:
sortChoose = originalData[[noteType, i]].sort_values(by=i,ascending=False) # 选择 教法 和 要测试的两列,并且按升序排序
maskA = sortChoose[noteType].isin(['A']) # 获取教法为 A 的行的 索引
aDataAll = sortChoose[maskA] # 获取 教法为A的行 的 完整的表
aDataAll = aDataAll.reset_index(drop=True) # 重置索引
aData = aDataAll[i] #获得a列数据
maskB = sortChoose[noteType].isin(['B']) # 获取教法为 B 的行的 索引
bDataAll = sortChoose[maskB] #教法为B的表
bDataAll = bDataAll.reset_index(drop=True) # 重置索引
bData = bDataAll[i]
abList = []
abList.append(aData)
abList.append(bData)
dataShowList.append(abList)
xLine = np.array(['计数','均值','标准差','最小值','25%','50%','75%','最大值'])
x = 0
for i in range(0, 2):
for j in range(0, 3):
data = dataShowList[x]
xIndex = data[0].describe().index #描述性统计的特征['count', 'mean', 'std', 'min', '25%', '50%', '75%', 'max']
y1 = data[0].describe().values
y2 = -data[1].describe().values
ax = plt.subplot2grid((2, 3), (i, j), colspan=1, rowspan=1) # 分为2行3列,从0,0开始,这个图占用第一行,第一列
ax.bar(xLine, y1, facecolor='#FF2718')
ax.bar(xLine, y2, facecolor='blue')
for m,n in zip(xLine,y1):
ax.text(m,n+20, '%.1f'%n,ha='center',va='top')
for m,n in zip(xLine,y2):
ax.text(m,n-20, '%.1f'%-n,ha='center',va='bottom')
x=x+1
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
plt.show()
最终结果:
可以看出,A种教学方法,均值在最后两次实现超越,25%,50%,75%处的数据在最后两次也实现超越,而标准差略微增大,说明离散程度增大(分化程度)。
那么离散程度或者说集中趋势是如何的呢?接下来用直方图的对比情况,来看一看。
代码:
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.ticker import MultipleLocator
tablePath = '1数据清洗后成绩.xlsx'
classTimeList = ['化学1','化学2','化学3','化学4','化学5','化学6']
noteType = '教法'
dataShowList = [] #存储成对的数据,A、B系列的data
# 导入测试的xls数据,并DataFrame化
originalData = pd.DataFrame(pd.read_excel(tablePath)) # 导入excel数据,并转化为DataFrame格式
for i in classTimeList:
sortChoose = originalData[[noteType, i]].sort_values(by=i,ascending=False) # 选择 教法 和 要测试的两列,并且按升序排序
maskA = sortChoose[noteType].isin(['A']) # 获取教法为 A 的行的 索引
aDataAll = sortChoose[maskA] # 获取 教法为A的行 的 完整的表
aDataAll = aDataAll.reset_index(drop=True) # 重置索引
aData = aDataAll[i] #获得a列数据
maskB = sortChoose[noteType].isin(['B']) # 获取教法为 B 的行的 索引
bDataAll = sortChoose[maskB] #教法为B的表
bDataAll = bDataAll.reset_index(drop=True) # 重置索引
bData = bDataAll[i]
#abList = []
dataShowList.append(aData)
dataShowList.append(bData)
#dataShowList.append(abList)
x = 0
xLine = np.arange(0,110,10) #0-100分为10段,作为x轴
yLine = np.arange(0,30,10) #0-20分为10段,作为y轴
#print(xLine)
for i in range(0, 6):
for j in range(0, 2):
data = dataShowList[x]
# yA = data[0].values
# yB = data[1].values
#xmajorLocator = MultipleLocator(10);
#ymajorLocator = MultipleLocator(2)
ax = plt.subplot2grid((6, 2), (i, j), colspan=1, rowspan=1) # 分为2行3列,从0,0开始,这个图占用第一行,第一列
kwargs = dict(histtype='bar', alpha=0.3, bins=10, rwidth=0.5, range=(0, 100)) #自定义涉及
ax.hist(data.values, **kwargs, color='red')
#ax.xaxis.set_major_locator(xmajorLocator)
#ax.yaxis.set_major_locator(ymajorLocator)
ax.set_xticks(xLine)
ax.set_yticks(yLine)
#ax.hist(yB, **kwargs,color='blue')
x =x+1
plt.rcParams['font.sans-serif']=['SimHei'] #用来正常显示中文标签
#plt.rcParams['axes.unicode_minus']=False #用来正常显示负号
# plt.xlim(0, 100)
# plt.ylim(0, 20)
plt.show()
结果:
从数据分布可以看出,最后两次的考试中,采用A教学方法的40-50分区间的学生人数,明显在逐渐向x轴右侧分布,而采用B教学方法的,这个区间并无太大变化,且高分学生数量减少。这是否说明A教学方法对于这个区间段学生有明显的改善效果?这个需要进一步研究分析。
注意,使用matplotlib作图的时候,会出现中文显示成方块问题,可以先用:
import sys
print(sys.path)
查看python3安装路径,再通过安装字体,更改库字体设置来解决。
开始的时候,觉得matplotlib坐标轴怎么总是重叠,许多的文字都看不清楚,实际如果使用vsCode,直接生成,会有一个简单的调整界面,调整好了再保存就好。
每个学生可以看做是一支股票(公司),每次考试可看作是股价(盈利情况),而每个学科可以看做是分公司,分公司的业绩即是每次考试各学科的分数,这样就可以借鉴一些较为成熟的商业分析方法,来对成绩进行分析预测。