目录
第1关:热力图显示XX重点地区
任务描述
本关任务:掌握使用pandas工具处理数据的基本知识以及使用seaborn.heatmap工具绘制热力图的方法。
相关知识
为了完成本关任务,你需要掌握:
- pandas.read_csv用法;
- 热力图的概念;
- seaborn.heatmap用法。
pandas.read_csv
以.csv为后缀名的文件是常见的数据集存储文件,pandas工具为我们提供了read_csv方法来读取并解析.csv文件。具体使用示例如下:
# 代码清单 1
import pandas as pd
df = pd.read_csv("./data/dataset.csv")
代码清单 1中,通过read_csv方法读取相对路径上的csv数据文件,并保存在pandas.DataFrame的对象里,这样我们就能通过DataFrame提供的数据处理方式对数据集进行各种各样的处理。
热力图
顾名思义,热力图就是一种能够反应“热度值”信息的直观图片,这里的“热度值”往往承载着我们所关注的一些物理信息,例如本实训案例中所涉及的“疫情热度”信息。
图1 热力图示例
如图 1所示,我们可以直观的通过图像中的“热度”信息感受到程度上的分布特征。
seaborn.heatmap
seaborn.heatmap可以直接接收pandas.DataFrame对象作为数据绘制二维热力图,此时两个维度上的坐标分别是pandas.DataFrame的index和column。
除了接收数据作为参数外,seaborn.heatmap还能接收其他参数进行更多的设置,这里介绍几个主要的常用参数:
参数 | 描述 |
---|---|
data | 绘图数据,作为第一个参数,不可为空 |
vmax | 绘制热力图时,展示热力数值的上限,可为空 |
vmin | 绘制热力图时,展示热力数值的下限,可为空 |
cmap | 定义热力图色彩样式,可为空 |
以下提供一个使用示例:
import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
# 接收一个 DataFrame 对象,绘制出相应的热力图
def drawHeatMap(df, vmax=None, vmin=None, cmap="Reds", figsize=(10,5)):
# 设置后,热力图上可以正常展示中文
sns.set(font="simhei")
# 设置单位热力区域的尺寸
f, ax = plt.subplots(figsize=figsize)
ax = sns.heatmap(df, vmax = vmax, vmin=vmin, cmap=cmap)
uniform_data = np.random.rand(10, 12)
drawHeatMap(uniform_data)
以上代码将会绘制出如下热力图:
图2 随机参数的热力图
编程要求
根据提示,在右侧编辑器 Begin-End 区域补充代码,针对提供给疫情数据绘制出相应的热力图。具体要求如下:
- 设置热力单位区域尺寸为 (10, 5);
- 正常显示中文;
- 设置配色样式为 "reds"。
测试说明
平台会对你编写的代码进行测试:
将你输出的图片与预期输出的图片进行对比。
代码:
import pandas as pd
import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df = pd.read_csv("./data/Wuhan-2019-nCoV.csv")
# 获取国家某时间点的疫情病例累计信息
def getDataByCountry(name,date):
tem = df.loc[(df['date']==date)&(df['country']==name) & (df['province']!=df['province'])]
if tem.empty:
return None
return tem.iloc[0]
# 获取省级区域某时间点的疫情病例累计信息
def getDataByProvince(name,date):
return df.loc[(df['date']==date)&(df['province']==name) & (df['city']!=df['city'])].iloc[0]
# 获取城市某时间点的疫情病例累计信息
def getDataByCity(name,date):
return df.loc[(df['date']==date)&(df['city']==name)].iloc[0]
# 定义区域范围
HuBeiCitys = [
"武汉市","黄石市","十堰市","宜昌市","襄阳市","鄂州市","荆门市",
"孝感市","荆州市","黄冈市","咸宁市","随州市","恩施土家族苗族自治州",
"仙桃市","潜江市","天门市",
]
# 定义时间范围,以一天作为步长,统计新增确诊病例数
HuBeiDates = [
'2020-01-31'
]
for i in range(29):
HuBeiDates.append("2020-02-{:02d}".format(i+1))
# 构建不同城市在时间范围内的累计确诊病例数的列表
HuBeiStore = {}
for city in HuBeiCitys:
HuBeiStore[city] = [getDataByCity(city,HuBeiDates[i])['confirmed'] for i in range(len(HuBeiDates))]
# 在累计确诊病例数,计算出每两天新增的确诊病例数,从而计算出两天内的疫情扩散指数。
HuBeiDaily = {}
for city in HuBeiCitys:
# 因标准变更,新增确诊病例数可能为负,这里统一作为 0 处理。
HuBeiDaily[city] = [max(0,(HuBeiStore[city][i+1]-HuBeiStore[city][i]))/HuBeiStore[city][i+1] for i in range(len(HuBeiDates)-1)]
# 创建用于绘制热力图的 DataFrame 对象
HuBeiDf = pd.DataFrame(HuBeiDaily, index=HuBeiDates[1:])
# 保存图片的路径
figPath = "./step1/target/result.jpg"
########## Begin ##########
# 请在此处填写绘制热力图的代码
sns.set(font="simhei")
f, ax = plt.subplots(figsize=(10,5))
ax = sns.heatmap(HuBeiDf,cmap="Reds")
########## End ##########
fig = ax.get_figure()
fig.savefig(figPath)
# 测试
from test import test
test("./step1/answer/answer.jpg","./step1/target/result.jpg")
开始你的任务吧,祝你成功!
第2关:排除异常采样点
任务描述
本关任务:在上一关卡的基础上,针对 2 月 7 日出现的异常采样点,采取步长为 2 天的方式来统计新增确诊病例,并绘制热力图。
相关知识
为了完成本关任务,你需要掌握:
-
关卡一热力图的异常点;
-
改变采样点步长。
关卡一热力图的异常点
相信你已经发现了关卡一中出现的一个异常点,即 2 月 7 日湖北省所有地区均无新增确诊病例:
通过上图我们可以发现,湖北省各地区在 2 月份的新增确诊病例主要集中在上旬,到下旬增长率明显放缓。但其中有一个异常的时间点:2 月 7 日。可能是数据本身的问题,也可能是因为当时政策标准的调整,2 月 7 日的新增病例远低于其“估计值”。
另外,我们还能发现XX市在 2 月 13 日出现了爆发式增长。
改变采样点步长
为了能够降低这些异常值对可视化图表带来的噪声干扰,在本案例中可以通过增加采样点步长的方式来进行“稀释”。
首先,解释下本案例热力图所描绘的“热力值”的概念:疫情扩散指数。
100%
举例来说:
XX市 2020-02-01 确诊: 4109
XX市 2020-02-02 确诊: 5142
那么XX市在 2020-02-02 疫情扩散指数为:
100% = 21.1%
此时采样步长为 1 天。如果要将步长改为两天的话,那么就需要将XX市在 2 月 3 号的确诊数减去 2 月 1 号的确诊数,然后再除以 2 月 3 号的确诊数,记为XX市在 2 月 3 号的疫情扩散指数。
编程要求
根据提示,在右侧编辑器 Begin-End 区域补充代码,在关卡一的基础上修改采样步长为 2 天,重新绘制湖北各地区在 2 月份的疫情热力图。具体要求如下:
- 热力图配色方案选择 "Reds",单元区域尺寸=(10,5);
- 时间采样步长为 2 天。
- 仅显示 2 月份偶数天的疫情扩散情况。
测试说明
平台会对你编写的代码进行测试:
检测实际绘制的热力图是否与答案匹配。
代码:
import pandas as pd
import seaborn as sns
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
df = pd.read_csv("./data/Wuhan-2019-nCoV.csv")
# 获取国家某时间点的疫情病例累计信息
def getDataByCountry(name,date):
tem = df.loc[(df['date']==date)&(df['country']==name) & (df['province']!=df['province'])]
if tem.empty:
return None
return tem.iloc[0]
# 获取省级区域某时间点的疫情病例累计信息
def getDataByProvince(name,date):
return df.loc[(df['date']==date)&(df['province']==name) & (df['city']!=df['city'])].iloc[0]
# 获取城市某时间点的疫情病例累计信息
def getDataByCity(name,date):
return df.loc[(df['date']==date)&(df['city']==name)].iloc[0]
# 定义区域范围
HuBeiCitys = [
"武汉市","黄石市","十堰市","宜昌市","襄阳市","鄂州市","荆门市",
"孝感市","荆州市","黄冈市","咸宁市","随州市","恩施土家族苗族自治州",
"仙桃市","潜江市","天门市",
]
########## Begin ##########
# 定义时间范围,以两天作为步长,统计新增确诊病例数
HuBeiDates = [
'2020-01-31'
]
for i in range(29):
HuBeiDates.append("2020-02-{:02d}".format(i+1))
########## End ##########
# 构建不同城市在时间范围内的累计确诊病例数的列表
HuBeiStore = {}
for city in HuBeiCitys:
HuBeiStore[city] = [getDataByCity(city,HuBeiDates[i])['confirmed'] for i in range(len(HuBeiDates))]
# 在累计确诊病例数,计算出每两天新增的确诊病例数,从而计算出两天内的疫情扩散指数。
HuBeiDaily = {}
for city in HuBeiCitys:
# 因标准变更,新增确诊病例数可能为负,这里统一作为 0 处理。
HuBeiDaily[city] = [max(0,(HuBeiStore[city][i+1]-HuBeiStore[city][i]))/HuBeiStore[city][i+1] for i in range(len(HuBeiDates)-1)]
# 创建用于绘制热力图的 DataFrame 对象
HuBeiDf = pd.DataFrame(HuBeiDaily, index=HuBeiDates[1:])
# 保存图片的路径
figPath = "./step2/target/result.jpg"
########## Begin ##########
# 请在此处填写绘制热力图的代码
sns.set(font="simhei")
f, ax = plt.subplots(figsize=(10,5))
ax = sns.heatmap(HuBeiDf, cmap="Reds")
########## End ##########
fig = ax.get_figure()
fig.savefig(figPath)
# 测试
from test import test
test("./step2/answer/answer.jpg","./step2/target/result.jpg")
开始你的任务吧,祝你成功!