内容正文:
第19课 数据处理与应用综合(见学生用书P102)
——4 数据处理与应用,教材第116~155页
基于Python程序设计语言,合理利用pandas,通过简单算法解决问题。
2023·浙江1月选考小红收集了部分城市2021年全年每天PM2.5、PM10、CO浓度数据,并将其分别保存在以8 位日期字符串命名的CSV文件中,部分文件如图1所示。每个文件记录了一天24小时的监测数据,示例如图2所示。
图1 图2
为统计分析城市A 2021年全年各月份PM2.5的月平均浓度(当月的日平均浓度的平均值),小红编写了一个Python程序。请回答下列问题。
(1)定义pmday() 函数,功能为:读取某天的CSV 文件,返回城市A 当天PM2.5 的日平均浓度。函数代码如下,横线处应填入的代码为__D__(单选,填字母)。
A.df['类型']=='PM2.5' B.df['类型'=='PM2.5']
C.df[df['类型']]=='PM2.5' D.df[df['类型']=='PM2.5']
import pandas as pd
def pmday(dayfile):
df=pd.read_csv(dayfile) # 读取文件dayfile 中的数据
df=____________
return df['城市A'].mean() # 返回城市A 当天PM2.5 的日平均浓度
(2)统计城市A 各月份PM2.5 的月平均浓度并绘制线形图,部分Python 程序如下。请在横线处填入合适的代码。
import matplotlib.pyplot as plt
def tstr(t):
if t<10:
return '0'+str(t)
else:
return str(t)
pm=[0]*12
mdays=[31,28,31,30,31,30,31,31,30,31,30,31] # 2021 年每月天数
for m in range(12):
sm=0
mstr=tstr(m+1)
for d in range(①__mdays[m]__):
dstr=tstr(d+1)
dayfile='2021'+mstr+dstr+'.csv'
sd=pmday(dayfile)
②__sm+=sd__
pm[m]=sm/mdays[m]
x=[1,2,3,4,5,6,7,8,9,10,11,12]
y=③__pm__
plt.plot(x,y) # 绘制线形图
# 设置绘图参数,显示如图3所示的线形图,代码略
图3
(3)城市A 2021年PM2.5的年平均浓度为34.6微克/立方米。由图3可知,城市 A 2021年PM2.5的月平均浓度超过年平均浓度的月份共有__5__个。
【解析】 (1)可以通过布尔型数据选取满足条件的行。课本P132中示例:如通过df1[df1[”借阅次数”]>30],可以检索df1 对象中“借阅次数”大于30的数据行。仿此例,结合下一行代码可知,筛选条件为df['类型']=='PM2.5',筛选对象为df,故选项D正确。
(2)变量m表示各月份对应的索引,mstr 表示各月份的数字字符串,以长度为2 的字符串来表示,不足两位的在前面补“0”,此功能由函数tstr() 来实现。不同月份的天数不同,为了计算各月份PM2.5 浓度的平均值,可以累加各月的每天PM2.5 浓度的平均值。变量dayfile 表示每天的数据文件名,题干已经提示“每天的数据分别保存在以8 位日期字符串命名的CSV 文件中”,调用函数pmday(dayfile) ,可以得到当天PM2.5 的日平均浓度,并保存于变量sd中。当月的各天PM2.5 的日平均浓度需要累加起来,最后求均值。因此①②空的答案依次为mdays[m]和sm+=sd。观察数据可视化的图像,可知横坐标为月份,即x表示的列表;纵坐标为PM2.5月平均浓度,而正是列表pm所表示的数据。③空答案为pm。
(3)城市A 2021年PM2.5的年平均浓度为34.6微克/立方米。观察图3可知,城市A 2021年PM2.5的月平均浓度超过年平均浓度的月份共有5个,分别为1、2、3、4、11月。
变式1 小林收集了2000 年~2022 年某省的GDP 数据,并将其存储于“info.csv”文件中,部分数据如图1 所示。
图1
为统计分析近20 多年来该省的经济情况,小林编写了Python 程序。请回答下列问题。
(1)定义js() 函数,功能为:计算每年GDP 的同比增长率[计算公式为:(本年度GDP-上一年GDP)/上一年GDP*100]。函数代码如下,请在横线处填入合适的代码。
def js(df):
for i in range(1,len(df)):
m=__df.at[i,'GDP']-df.at[i-1,'GDP']__
df['RATE'][i]=round(m/df['GDP'][i-1]*100,2)
return df
(2)统计2000 年~2022 年期间该省GDP 增长率在8%及以上的最长持续时间(若有多个长度相同的最大值,输出最新的时间段),并绘制线形图。部分Python 程序如下,请在横线处填入合适的代码。
import pandas as pd
import matplotlib.pyplot as plt
plt.rcParams['font.sans——serif']=['SimHei']
df=pd.read_csv('info.csv',encoding='gbk')
df=js(df)
t=8
k=0
maxk=0
pos=0
for i in range(len(df)):
if①__df.at[i,'RATE']>=t__:
k+=1
else:
if k>=maxk:
maxk=k
②__pos=i-k____
k=0
df2=df[pos:pos+maxk]
x=③__x=df2['YEAR']__
y=df2['RATE']
plt.plot(x,y) #绘制线形图
#设置绘图参数,显示如图2 所示的线形图,代码略
(3)由图2 可知,GDP 增长率最高的年份是__2003____年。
图2
【解析】 (1)采用at 函数获取DataFrame 对象位于索引行字段名列的单个数据。从索引行1 开始遍历,i-1 表示上一年度,根据公式可知,变量m 是本年度GDP 减去上一年GDP 的差值。
(2)①根据题目要求可知,查找的条件为GDP 增长率在8%及以上。②找到持续增长的开始年份,变量i 表示不再持续增长的年份,k表示持续的时间,因此持续增长的开始年份为i-1-k+1,即i-k。③制作图表的X 轴数据源,由图表可知X 轴是持续增长所有的年份,语句df2=df[pos:pos+maxk] 为持续增长年份的记录。
(3)由图可知,2003年GDP增长率最高。
变式2 针对选考2024·柯桥中学检测某中学“七选三”选考科目的选科数据存储在Excel 文件“选科数据.xlsx”中,部分数据及格式如图1 所示。图中“1”表示选择该科目为选考科目。现对数据进行统计分析,编写Python 程序。请回答下列问题。
图1
(1)定义fenban()函数,功能为:根据选考科目选报的总人数allrs 以及每个班的最多人数maxbrs来计算需开设的班级数。函数代码如下,请在横线处填入合适的代码。
def fenban(allrs,maxbrs):
bjnum=allrs//maxbrs
if__allrs%maxbrs!=0__或allrs%maxbrs>0__或bjnum*maxbrs<allrs__:
bjnum+=1
return bjnum
(2)统计“七选三”各科的选报人数,输出各科的选报情况及开班情况,如图2所示。部分Python程序如下,请在横线处填入合适的代码。
图2 图3
import pandas as pd
df=pd.read_excel(”选科数据.xlsx”)
km=[”物理”,”化学”,”生物”,”政治”,”历史”,”地理”,”技术”]
m=40 #每个班的最多人数
bj=[0]*7
xkrs=[0]*7 #存储选考科目的选报人数
p=0
for j in km:
①__cnt=0__
for i in range(len(df)):
if df.at[i,j]==1:
cnt+=1
②__xkrs[p]__或xkrs[km.index(j)]__=cnt
bj[p]=fenban(cnt,m)
p=p+1
for i in range(7):
print(km[i],”人数: ”,xkrs[i],”班级数: ”,bj[i])
(3)根据选考科目选报人数情况绘制柱形图,如图3所示。部分Python 程序如下,请在横线处填入合适的代码。
import matplotlib.pyplot as plt
x=km
y=__xkrs____
plt.bar(x,y) #绘制柱形图
#设置绘图参数,显示如图3 所示的柱形图,代码略
(4)下列程序能实现按班级统计各班选报技术学科人数的是__C__(单选,填字母)。
A.jsrs_bj=df.groupby(”班级”).”技术”.count()
B.jsrs_bj=df.sort_values(”班级”).count()
C.jsrs_bj=df.groupby(”班级”)[”技术”].count()
D.jsrs_bj=df.groupby(”班级”).技术.mean()
【解析】 (1)当选报总人数allrs 是每班最多人数maxbrs 的倍数时,开设的班级数为bjnum,否则需要再增加一个班级, 因此横线处应填入的代码为allrs%maxbrs!=0,也可以写为allrs%maxbrs>0 或bjnum*maxbrs<allrs。
(2)变量cnt 用来存储选考科目的选报人数,因此在统计每门学科的选报人数前,需将cnt 清0,因此①处代码为cnt=0;②处代码的功能是记录当前学科的选报人数,因此代码为xkrs[p],也可以写为xkrs[km.index(j)]。
(3)观察图3 可知,图表的纵坐标数据为各科的选报人数,因此答案为xkrs。
(4)根据题目要求可知,选项C正确。
|随|堂|检|测|
1.针对选考张三同学收集了一个地区8 月各类共享单车的骑行数据记录,并将每天的用户数据存储于“sharedbikes.xlsx”文件中,不考虑跨天数据,部分数据格式如图1 所示。
图1
请回答下列问题。
(1)定义cal() 函数,功能为:将Excel文件中的时间数据的小时和分钟部分转换为分钟格式并返回。例如,从“2023/8/20 6:57”获取“6:57”并将其转换为417(6*60+57=417)。部分Python程序如下,请在横线处填入合适的代码。
def cal(s):
n=len(s)
for i in range(n):
if s[i]==” ”: #如果为空格字符
p=i
if s[i] ==”:”:
q=i
t=__60__*__int(s[p+1:q])__+int(s[q+1:])
return t
(2)统计该月各类共享单车的每天平均骑行时长,并绘制柱形图,如图2所示。部分Python程序如下,请在横线处填入合适的代码。
图2
import pandas as pd
import matplotlib.pyplot as plt
df=pd.read_excel(”sharedbikes.xlsx”)
bike=[”哈啰单车”,”摩拜单车”,”美团单车”,”青桔单车”]
sm=[0] * 4
avg=[0] * 4
days=31
for i in ①__df.index__或range(len(df))__:
t=cal(df.at[i,”结束时间”])-cal(df.at[i,”开始时间”])
for j in range(4):
if df.at[i,”APP 类型”]==bike[j]:
②__sm[j]+=t__
break
for i in range(4):
avg[i]=sm[i]/days
plt.figure(figsize=(12,4))
x=bike
y=③__avg__
plt.bar(x,y)
plt.show()
(3)统计该月各类共享单车的骑行次数,下面的程序中加框处代码有误,可将其改正为__D__(单选,填字母:A.max();B.min();C.mean();D.count())。
n=df.groupby(”APP 类型”,as_index=True).用户编号.
【解析】 (1)遍历骑行时间字符串“2022/8/20 6:57”的索引,如果对应的字符是空格,则用变量p 记住空格的索引,如果对应的字符是“:”,则用变量q 记住冒号的索引,遍历结束,提取小时为s[p+1:q],通过int() 函数转换成整数,再将小时转换为分钟。横线处填60* int(s[p+1:q])
(2)由后面的代码“df.at[i,”APP 类型”]==bike[j]”可知,变量i 表示数据集的索引。循环语句“for i in ①: ”是遍历数据集df 的索引,所以①处填range(len(df)) 或df.index;如果第i 条记录的“APP 类型”等于bike[j],表示bike[j]类型单车的骑行时间增加了t 分钟,结合后面的代码“for i in range(4): avg[i]=sm[i]/days”可知,数组sm存储的是对应单车类型的总骑行时长。②处是bike[j]类型单车的骑行时间增加,所以填sum[j]+=t;由图表的显示内容可知,横坐标是显示变量x 的值(单车类型),纵坐标是显示变量y 的值(单车的骑行平均时长),平均时长存储在数组avg 中,所以③处填avg。
(3)题目要求统计骑行次数,即数据的个数,所以统计函数应该是count(),故选项D正确。
2.2024·金华一中检测为研究某项疾病与年龄的关系,某医院对以前的诊断记录进行整理和分析,整理的部分数据如图1所示。
姓名
年龄
疾病
毕蕴琪
52
疾病A
蔡丹婷
26岁
疾病D
蔡伟剑
十四岁
疾病E
陈芝伊
78
疾病B
丁佳菲
35
疾病A
……
……
……
图1 图2
(1)图1 所示的数据中,“年龄”列数据的格式不一致。为了便于数据分析,需要先进行数据处理。下列操作正确的是__D__(单选,填字母)。
A.删除“年龄”列数据
B.将“年龄”列数据中含有中文文字的记录删除
C.将“年龄”列数据转为文本类型
D.将“年龄”列数据中含有中文文字的记录修改为只包含数字的年龄
(2)将数据整理好后,统计0~18、19~35、36~60、61 及以上四个年龄段的某疾病患病人数占该疾病总患病人数的比例,并绘制柱形图,如图2所示。部分Python 程序如下,请在横线处填入合适的代码。
import pandas as pd
import matplotlib.pyplot as plt
df=pd.read_excel('data.xlsx')
tp=input('请输入疾病类型: ')
df1=①__df[df.疾病==tp]__ # 筛选tp 疾病的数据
count=[0] * 4
for i in range(len(df1)):
age=df.at[i,”年龄”]
if ②__age<=18__:
count[0]+=1
elif age<=35:
count[1]+=1
elif age<=60:
count[2]+=1
else:
count[3]+=1
x=['0~18','19~35','36~60','61 及以上']
y=[]
for i in range(4):
y.append(③__count[i]/len(df1)*100__)
plt.bar(x,y) # 显示不同年龄段患该病的人数比例
# 设置图表其他参数,代码略
plt.show()
(3)观察图2,“疾病A”患病比例最大的年龄段为__0~18__。
(4)获取61 岁及以上的人群中患病率最高的10 种疾病。部分Python程序如下:
def get_head10(df,age):
return df.疾病.head(10)
print(get_head10(df,61))
上述程序段中加框处的代码由以下三部分组成:
①df=df.sort_values(”年龄”,ascending=False)
②df=df[df.年龄>=age]
③df=df.groupby(”疾病”,as_index=False).count()
下列选项中,代码顺序正确的是__D__(单选,填字母)。
A.①②③ B.①③② C.②①③ D.②③①
【解析】 (1)根据数据处理的基本思路以及相关代码,这里最合适的操作是将“年龄”列的数据修改为只包含数字。
(2)①筛选的正确代码:df[df['疾病类型']==tp]。
②根据题意和相应的代码可知,这里的条件是:age<=18。
③注意图2 上的数据以及坐标信息:count[i]/sum(count)*100。
(3)图上可看出,患病比例最大的年段是0~18。
(4)数据处理的顺序是:筛选、分组统计、排序(降序),选项D正确。
温馨提示:请完成高效作业19 )
学科网(北京)股份有限公司
$$