第八章 Pandas可视化

目录

第1关:热力图显示XX重点地区

任务描述

相关知识

pandas.read_csv

热力图

seaborn.heatmap

编程要求

测试说明

代码:

第2关:排除异常采样点

任务描述

相关知识

关卡一热力图的异常点;

改变采样点步长。

编程要求

测试说明

代码:


第1关:热力图显示XX重点地区

任务描述

本关任务:掌握使用pandas工具处理数据的基本知识以及使用seaborn.heatmap工具绘制热力图的方法。

相关知识

为了完成本关任务,你需要掌握:

  1. pandas.read_csv用法;
  2. 热力图的概念;
  3. 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 天的方式来统计新增确诊病例,并绘制热力图。

相关知识

为了完成本关任务,你需要掌握:

  1. 关卡一热力图的异常点;

  2. 改变采样点步长。

关卡一热力图的异常点
相信你已经发现了关卡一中出现的一个异常点,即 2 月 7 日湖北省所有地区均无新增确诊病例:

 通过上图我们可以发现,湖北省各地区在 2 月份的新增确诊病例主要集中在上旬,到下旬增长率明显放缓。但其中有一个异常的时间点:2 月 7 日。可能是数据本身的问题,也可能是因为当时政策标准的调整,2 月 7 日的新增病例远低于其“估计值”。

另外,我们还能发现XX市在 2 月 13 日出现了爆发式增长。

改变采样点步长
为了能够降低这些异常值对可视化图表带来的噪声干扰,在本案例中可以通过增加采样点步长的方式来进行“稀释”。

首先,解释下本案例热力图所描绘的“热力值”的概念:疫情扩散指数。

疫情扩散指数 = \frac{某时间段内新增确诊病例}{截至该时间段累计确诊病例} \times 100%

举例来说:

XX市 2020-02-01 确诊: 4109
XX市 2020-02-02 确诊: 5142

那么XX市在 2020-02-02 疫情扩散指数为:

疫情扩散指数\left ( 武汉,2020/2/2 \right )= \frac{5142 - 4109}{5142} \times 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")

开始你的任务吧,祝你成功!

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值