目录
语言:python
工具:jupyter
前提
所需要导入的库有
- numpy
- pandas
代码分步解说
首先导入库,并重命名
#numpy运算库 矩阵
import numpy as np
#pandas 做业务表格处理
import pandas as pd
加载原始数据
读取表18级高一体测记录.xlsx
records = pd.read_excel(r'C:\Users\1\Desktop\18级高一体测记录汇总.xlsx')
#可直接用records进行输出jupyter默认的
#head默认显示表格前5行
records.head()'C:\Users\1\Desktop\18级高一体测记录汇总.xlsx')
读取打分标准表(体测评分标准)
score_table = pd.read_excel(r'C:\Users\1\Desktop\体测评分标准.xlsx',header=[0,1],index_col=[0])
#header=[0,1] 将前两行进行固定 ;index_col=[0]将第一行进行 行索引
score_table.head()
空值 重复值
判断空值isnull(); 求均值mean();
#先判断是否空值isnull();再求均值,即求每一列的True的均值mean()
#Fasle 0; True 1;
records.isnull().mean()
可以看到当列表中有空值的时候,返回True。再求均值就可以看到哪一些中是有空值存在,由此进行判断。
在上一步中我们判断出表格中有空值,所以现在我们对它进行填充,对所有空格进行0值填充。
填充fillna()
records = records.fillna(0)
records
再进行验证一下,可以看到空值不见了,已经被0值填充。
records.isnull().mean()
表格数据类型数据处理 records.info()
我们先是对表格信息进行查询,如下所示
要知道分数中的分秒不好识别比较易出错,所以我们把它转换为数值,如下所示
def transformer(time_obj):
if isinstance (time_obj,str): #用isinstance来判断是否为字符串类型
minute,seconds = time_obj.split("'")
return int(minute)+int(seconds)/60
else:
return 0
records['1000米'] = records['1000米'].map(transformer)
records
1000米打分
第一步:去除score_table中的1000米成绩的时间类型中的多余部分,并转换成普通数值。
def strip_fh(x):
return x.strip('"')
score_table[('1000米','成绩')] = score_table[('1000米','成绩')].map(strip_fh)
score_table[('1000米','成绩')] = score_table[('1000米','成绩')].map(transformer)
score_table
我们可以看到,体测评分标准 中的1000米成绩变成了数值部分而不是分秒。
第二步:提取1000米成绩
#提取1000米成绩
m_1000 = score_table['1000米']
def calculate(x):
if x == 0:
return 0
select = x <= m_1000['成绩']
if select.sum() <= 0:
return 0
return m_1000.loc[select,'分数'].iloc[0]
第三步:运行
records['1000米分数'] = records['1000米'].map(calculate)
records
可以看到在最后一列,‘1000米分数’ 运行评分成功。
同理
50米打分
#提取50米成绩
m_50 = score_table['50米']
def calculate_50(x):
if x == 0:
return 0
select = x <= m_50['成绩']
if select.sum() <= 0:
return 0
return m_50.loc[select,'分数'].iloc[0]
records['50米分数'] = records['50米'].map(calculate_50)
records
跳远打分
由于跳远打分是数值越大分越高,所以 select = x >= far_score
#提取跳远成绩
far_score = score_table['跳远']
def calculate_far(x):
if x == 0:
return 0
select = x >= far_score['成绩']
if select.sum() <= 0:
return 0
return far_score.loc[select,'分数'].iloc[0]
records['跳远分数'] = records['跳远'].map(calculate_far)
records
肺活量打分
#提取肺活量成绩
live_score = score_table['肺活量']
def calculate_live(x):
if x == 0:
return 0
select = x >= live_score['成绩']
if select.sum() <= 0:
return 0
return live_score.loc[select,'分数'].iloc[0]
records['肺活量成绩'] = records['肺活量'].map(calculate_live)
records
BMI指标
#KG/M^2
M2 = (records['身高']/100)**2
KG = records['体重']
BMI = KG/M2
records['BMI']=BMI
records
一键运行
#封装一个转换时间类型的函数 解决1000米 50米问题
def transformer(time_obj):
if isinstance (time_obj,str): #用isinstance来判断是否为字符串类型
minute,seconds = time_obj.split("'")
return int(minute)+int(seconds)/60
else:
return 0
#去除score_table中的1000米成绩的时间类型中的多余部分
def strip_fh(x):
return x.strip('"')
#1000米打分映射逻辑
m_1000 = score_table['1000米']
def calculate(x):
if x == 0:
return 0
select = x <= m_1000['成绩']
if select.sum() <= 0:
return 0
return m_1000.loc[select,'分数'].iloc[0]
#50米打分映射逻辑
m_50 = score_table['50米']
def calculate_50(x):
if x == 0:
return 0
select = x <= m_50['成绩']
if select.sum() <= 0:
return 0
return m_50.loc[select,'分数'].iloc[0]
#跳远打分映射逻辑
far_score = score_table['跳远']
def calculate_far(x):
if x == 0:
return 0
select = x > far_score['成绩']
if select.sum() <= 0:
return 0
return far_score.loc[select,'分数'].iloc[0]
#肺活量打分映射逻辑
live_score = score_table['肺活量']
def calculate_live(x):
if x == 0:
return 0
select = x > live_score['成绩']
if select.sum() <= 0:
return 0
return live_score.loc[select,'分数'].iloc[0]
#传入两个路径
def main_logic(records_path,score_table_path):
#加载原始数据
records = pd.read_excel(records_path)
score_table = pd.read_excel(score_table_path,header=[0,1],index_col=[0])
#对空值处理
records = records.fillna(0)
#对记录表中的1000米进行时间类型转换
records['1000米'] = records['1000米'].map(transformer)
#去除1000米成绩的时间类型中的多余部分
score_table[('1000米','成绩')] = score_table[('1000米','成绩')].map(strip_fh)
#对记录表中的1000米做时间类型做转换
score_table[('1000米','成绩')] = score_table[('1000米','成绩')].map(transformer)
#1000米打分
records['1000米分数'] = records['1000米'].map(calculate)
#50米打分
records['50米分数'] = records['50米'].map(calculate_50)
#跳远打分
records['跳远分数'] = records['跳远'].map(calculate_far)
#肺活量
records['肺活量成绩'] = records['肺活量'].map(calculate_live)
#BMI
M2 = (records['身高']/100)**2
KG = records['体重']
records['BMI']= KG/M2
#运行
main_logic(r'C:\Users\1\Desktop\18级高一体测记录汇总.xlsx',r'C:\Users\1\Desktop\体测评分标准.xlsx')
records
结果输出图:
优化操作
因为上一个的一键操作中有许多重复相似的用法,所以可以对它进行进一步的优化。可以看到这个优化解决了公式的通用重复和4列数据的映射途径,大大缩减了代码的行数节省了空间,时间。
#封装一个转换时间类型的函数 解决1000米 50米问题
def transformer(time_obj):
if isinstance (time_obj,str): #用isinstance来判断是否为字符串类型
minute,seconds = time_obj.split("'")
return int(minute)+int(seconds)/60
else:
return 0
#去除score_table中的1000米成绩的时间类型中的多余部分
def strip_fh(x):
return x.strip('"')
def calculate_normal(x,flag):
#判断空值(被填充为0的值,是缺考,所以直接给0分)
if x == 0:
return 0
#判断是越大分越高(跳远、肺活量),还是越小分越高(50米、1000米)
if flag == True:
select = x <= m_1000['成绩']
else:
select = x > m_1000['成绩']
if select.sum() <= 0:
return 0
return m_1000.loc[select,'分数'].iloc[0]
#传入两个路径
def main_logic(records_path,score_table_path):
#加载原始数据
records = pd.read_excel(records_path)
score_table = pd.read_excel(score_table_path,header=[0,1],index_col=[0])
#对空值处理
records = records.fillna(0)
#对记录表中的1000米进行时间类型转换
records['1000米'] = records['1000米'].map(transformer)
#去除1000米成绩的时间类型中的多余部分
score_table[('1000米','成绩')] = score_table[('1000米','成绩')].map(strip_fh)
#对记录表中的1000米做时间类型做转换
score_table[('1000米','成绩')] = score_table[('1000米','成绩')].map(transformer)
#解决4列数据的映射途径
columns = ['1000米','50米','跳远','肺活量']
for col in columns:
flag_data = col in ['1000米分数','50米分数']
#caculate_normal函数,是一个通用的映射函数,用来打分
records[col+'分数'] = records[col].apply(calculate_normal,flag=flag_data)
#BMI
M2 = (records['身高']/100)**2
KG = records['体重']
records['BMI']= KG/M2
#运行
main_logic(r'C:\Users\1\Desktop\18级高一体测记录汇总.xlsx',r'C:\Users\1\Desktop\体测评分标准.xlsx')
records
结果输出图:
总结
这一部分虽然看着很多,其实后面都是对前面的的分步进行总结、升华。先将分步的代码掌握好也是非常重要的,不要想着一口能吃成大胖子。然后再将分步中的代码结合起来,做到完整收纳融合。最后,才开始去想如何提升自己的代码,做进一步的升华,这样才能做到事半功倍。
等我们啥时候打够10000行代码后,我们的熟练度也会不断提升的,让我们一起加油吧。今天这一篇更了五千多字,好累啊!所以看到这里的友友觉得有用就点个赞吧,你的赞将是我的动力
o(* ̄▽ ̄*)ブ加油!加油!