老师给了题目做,但是在网上搜不到现成的,花了心思。做的时候很大部分是可以直接根据pandas的中文API文档上提示就能做出来(小伙伴们要养成习惯看官方文档,可能能事半功倍)
题目、源excel数据、代码、结果截屏如有需要可以直接去这儿下载
题目:
这是老师给的题目,我后面会根据题目的数量分十三步来依次讲解。有哪一部分的需要就直接跳到那一步就可以了,注意:注释的地方也重要!!!!(因为下方要使用到的函数,我在上方就可能写注释解释一下)
excel表数据:
第一题:找出缺考或NaN的学生及课程
import pandas as pd
import numpy as np
data_url = 'F:/Python_Homework/homework_data.xls' #就是源数据excel表
data = pd.read_excel(data_url) #打开文件
#print(data) #打印读取的数据
# print(data.columns.values.tolist()) #打印表头
# print(data.columns.values.tolist()[0]) #打印第一列的表名
# print(data.index.values.tolist()) #打印行名
# print(data.shape) #返回的一个元组,得据的行数和列到数数
# print(data.iloc[4,5]) #返回第四行第五列的数
a , b =data.shape #获取行数和列数
for indexs in range(a):
for columns in range(4,b):
#注意:判定一个数值是否为空时,需要使用numpy.nan来定义空值
if data.iloc[indexs,columns] == '缺考' or data.iloc[indexs,columns] is np.NaN:
print("学号:",data.iloc[indexs,0],",姓名:",data.iloc[indexs,2],",科目:",data.columns.values.tolist()[columns])
第二题:将这些课程成绩设置为0
import pandas as pd
import numpy as np
data_url = 'F:/Python_Homework/3_DataOperate/homework_data.xls'#就是源数据excel表
data = pd.read_excel(data_url)
#行不通!!!
# data.fillna(0) #用x替换DataFrame对象中所有的空值
# print(data)
a , b =data.shape #获取行数和列数
for indexs in range(a):
for columns in range(4,b):
if data.iloc[indexs,columns] == '缺考' or data.iloc[indexs,columns] is np.NaN:
data.iloc[indexs,columns] = 0
#将修改后的数据存储为新文件
#注意:写上index = False属性是为了防止创建文件时默认添加索引,从而防止了索引的重复
data.to_excel('F:/Python_Homework/3_DataOperate/homework_data_SetZero.xls', index = False)
第三题:找出各科的最高分、最低分、平均分
import pandas as pd
data_url = 'F:/Python_Homework/3_DataOperate/homework_data_SetZero.xls'#把空值缺考的那项设成0之后的excel表
data = pd.read_excel(data_url)
a , b = data.shape #获取行数和列数
#得到平均分
for columns in range(4,b):
ClassName = data.columns.values.tolist()[columns] #得到列名
print("科目:",ClassName,"的平均分为:%.2f"%data[f"{ClassName}"].mean()) #使用格式化输出中的f'{values}'行得通
print('-'*20)
#得到最大值
for columns in range(4,b):
ClassName = data.columns.values.tolist()[columns]
print("科目:",ClassName,"的最大值为:",data[f"{ClassName}"].max())
print('-'*20)
#得到最小值
for columns in range(4,b):
ClassName = data.columns.values.tolist()[columns]
print("科目:",ClassName,"的最小值为:",data[f"{ClassName}"].min())
第四题:找出每个学生的最高分、最低分、平均分
import pandas as pd
data_url = 'F:/Python_Homework/3_DataOperate/homework_data_SetZero.xls'
data = pd.read_excel(data_url)
# print(data.loc[2]) #返回索引指向的那一行数据
# print(data.iloc[0,:]) #返回第一行数据
# print(data.iloc[0,4:]) #返回第一行的第五列到最后一列的数据
# print(data.iloc[0,4]) #返回第一行的第五列数据
a , b = data.shape # #获取行数和列数
for indexs in range(a):
print('姓名:',data.iloc[indexs,2],'的平均得分:%.2f'%data.iloc[indexs,4:].mean())
print('-'*20)
for indexs in range(a):
print('姓名:',data.iloc[indexs,2],'的最大得分:',data.iloc[indexs,4:].max())
print('-'*20)
for indexs in range(a):
print('姓名:',data.iloc[indexs,2],'的最小得分:',data.iloc[indexs,4:].min())
第五题:找出各班各科的最高分、最低分、平均分
代码中会使用groupby()来分组,想细致看看groupby()怎么使用的,请访问:https://blog.csdn.net/weixin_38168620/article/details/80100201
import pandas as pd
data_url = 'F:/Python_Homework/3_DataOperate/homework_data_SetZero.xls'
data = pd.read_excel(data_url)
# data.groupby(col1) #返回按列col1分组
# data.groupby(col1).size() #返回按列col1分组的个数统计
print("平均分为:")
mean = data[['英语','体育','军训','数分','高代','解几']].groupby(data['班级']).mean()
print(mean)
print('-'*20)
print("最高分为:")
max = data[['英语','体育','军训','数分','高代','解几']].groupby(data['班级']).max()
print(max)
print('-'*20)
print("最低分为:")
min= data[['英语','体育','军训','数分','高代','解几']].groupby(data['班级']).min()
print(min)
第六题:找出每个学生的最高分、最低分的科目
import pandas as pd
data_url = 'F:/Python_Homework/3_DataOperate/homework_data_SetZero.xls'
data = pd.read_excel(data_url)
a , b = data.shape
#最好成绩
for indexs in range(a):
max = data.iloc[indexs,4] #将每个学生的成绩的最大值设为英语成绩
flag = 4 #flag用来指向列
for columns in range(5,b):
if max < data.iloc[indexs,columns]:
flag = columns
print('姓名:',data.iloc[indexs,2],'成绩最好的科目名称是:',data.columns.values.tolist()[flag])
print('-'*20)
#最差成绩
for indexs in range(a):
min = data.iloc[indexs,4] #将每个学生的成绩的最小值设为英语成绩
flag = 4 #flag用来指向列
for columns in range(5,b):
if min > data.iloc[indexs,columns]:
flag = columns
print('姓名:',data.iloc[indexs,2],'成绩最差的科目名称是:',data.columns.values.tolist()[flag])
第七题:统计各科及格的人数
import pandas as pd
data_url = 'F:/Python_Homework/3_DataOperate/homework_data_SetZero.xls'
data = pd.read_excel(data_url)
#data[data[col] > 0.5] #选择col列的值大于0.5的行
a , b = data.shape #获取行数和列数
for columns in range(4,b):
ClassName = data.columns.values.tolist()[columns] #得到列名
num = data[data[f"{ClassName}"] >= 60]
print("科目:",ClassName,"的及格人数为:",len(num))
# print("科目:",ClassName,"的及格人数为:",num.count())#有误!!!
第八题:按总成绩排名
import pandas as pd
data_url = 'F:/Python_Homework/3_DataOperate/homework_data_SetZero.xls'
data = pd.read_excel(data_url)
list1 = [] #创建一个列表
a , b =data.shape
for indexs in range(a):
Sum = 0
for columns in range(4,b):
Sum += data.iloc[indexs,columns]
list1.append(Sum)
#data['add_col']=values是最简单的一方法增加一列
#不能直接data["总成绩"] = list1,因为可能出现长度不匹配。所以需要转化为Series
data["总成绩"] = pd.Series(list1)
#data.sort_values(col) #对特定列进行排序。默认为升序;ascending=False则为降序排列
# 注意:不会改变原来的DataFrame的对象,即:print(data)和data.sort_values(col)是不一样的!!!
print(data.sort_values('总成绩'))
第九题:按男、女生统计各科成绩(最高分、最低分、平均分)
import pandas as pd
data_url = 'F:/Python_Homework/3_DataOperate/homework_data_SetZero.xls'
data = pd.read_excel(data_url)
# data.groupby(col1) #返回按列col1分组
# data.groupby(col1).size() #返回按列col1分组的个数统计
print("平均分为:")
mean = data[['英语','体育','军训','数分','高代','解几']].groupby(data['性别']).mean()
print(mean)
print('-'*20)
print("最高分为:")
max = data[['英语','体育','军训','数分','高代','解几']].groupby(data['性别']).max()
print(max)
print('-'*20)
print("最低分为:")
min= data[['英语','体育','军训','数分','高代','解几']].groupby(data['性别']).min()
print(min)
第十题:计算每科成绩的相关性
import pandas as pd
data_url = 'F:/Python_Homework/3_DataOperate/homework_data_SetZero.xls'
data = pd.read_excel(data_url)
#data[[col1,col2,..]]是为了截取特定的列来组成新的DataFrame对象
data1 = data[['英语','体育','军训','数分','高代','解几']]
print(data1.corr())
第十一题:各科前三名的名单
import pandas as pd
data_url = 'F:/Python_Homework/3_DataOperate/homework_data_SetZero.xls'
data = pd.read_excel(data_url)
a , b =data.shape
for columns in range(4,b):
ClassName = data.columns.values.tolist()[columns] #获取列的名字
print('科目:',ClassName,'前三名名单:')
print(data.sort_values(f'{ClassName}',ascending=False).iloc[0:3,0:3])
第十二题:成绩0修改成平均值
import pandas as pd
import numpy as np
data_url = 'F:/Python_Homework/3_DataOperate/homework_data_SetZero.xls'
data = pd.read_excel(data_url)
a , b =data.shape #获取行数和列数
for indexs in range(a):
for columns in range(4,b):
if data.iloc[indexs,columns] == 0:
data.iloc[indexs,columns] = int(data.iloc[indexs,4:].mean())
#将修改后的数据存储为新文件
#注意:写上index = False属性是为了防止创建文件时默认添加索引,从而防止了索引的重复
data.to_excel('F:/Python_Homework/3_DataOperate/homework_data_ZeroChangeMean.xls', index = False)
第十三题:各科成绩分布图
没怎么接触matplotlib画图,所以在看懂了网址:https://www.sohu.com/a/319358849_797291绘制成绩饼状图后写的,总体没错,但是图的分类有点对不上
import pandas as pd
from itertools import groupby
import matplotlib.pyplot as plt
data_url = 'F:/Python_Homework/3_DataOperate/homework_data_ZeroChangeMean.xls'
data = pd.read_excel(data_url)
#创建一个字典,存放课程及其成绩
dict1 = {}
a , b =data.shape
for columns in range(4,b):
ClassName = data.columns.values.tolist()[columns] #获取列的名字
list1 = [] #创建一个列表
for indexs in range(a):
list1.append(data.iloc[indexs,columns]) #列表中存放一个课程中的所有成绩
dict1[f"{ClassName}"] = list1 #将字典的key与values匹配
##打印字典
# for key,value in dict1.items():
# print(f'{key} = {value}')
#判断优秀
def select(score):
if score >= 85:
return '优秀'
elif score >=60:
return '及格'
else:
return'不及格'
#统计每门课中优秀、及格、不及格的人数
#字典dict2的格式为{'课程名称1':{'优秀':3,'及格':3,'不及格':6},'课程名称2':{'优秀':0,'及格':1,'不及格':2},....}
dict2 = dict1
for x , y in dict1.items():
dict2[x] = {}
#groupby()需要对原始数组进行排序才能正确分类
#(1)groupby()将key函数(即本代码中selec())作用于原循环器的各个元素。
#(2)根据key函数(即本代码中selec())结果,将拥有相同函数结果的元素分到一个新的循环器。
#(3)每个新的循环器以函数返回结果为标签。
for category , num in groupby(sorted(y),select):
dict2[x][category] = len(tuple(num))
#设置图形中的中文字体
plt.rcParams['font.sans-serif'] = ['simhei']
#创建6个子图
fig,axs = plt.subplots(2,3)
axs.shape = 1,6
#依次在六个子图中绘制每门课程的饼状图
for index,subjectData in enumerate(dict2.items()):
# 选择子图
plt.sca(axs[0][index])
subjectName , subjectRation = subjectData
plt.pie(list(subjectRation.values()),labels=list(subjectRation.keys()),autopct='%1.1f%%')
plt.xlabel(subjectName)
plt.legend()
plt.show()
结果为: