疫情数据提取

基于正则表达式提取新冠疫情数据

这篇博客主要基于新冠数据进行每日新增病例与累计病例的统计

开发环境:Pycharm 2019.1.1 + python 3.7

一、数据集介绍

数据集中的数据是从2019年12月31到2019年2月28日的新闻数据。

地区信息由“provinceName”标识,其中,每个省份对应着不同的’provinceId’

原始数据属性(部分)为:

属性标签含义
id标识各条新闻
pubDate新闻发布时间
title新闻标题
summary新闻摘要(主要内容)
infoSource新闻来源
provinceId地区ID
provinceName地区名称

示例:
在这里插入图片描述

二、数据处理

  1. 数据清洗

    显然,要从新闻数据中提取湖北和全国每天的新冠肺炎的新增确诊病例数,累计确诊病例数,许多数据属性(如id, infoSource, sourceUrl)是无效的。经过筛选,其中有用的数据属性仅有’pubDate’, ‘title’, ‘summary’, ‘provinceId’ 四种。

    使用pandas进行数据清洗,完成后将数据输出为CSV文件。代码如下:

   # -*- coding:utf-8 -*-
   
   import pandas as pd
   data = pd.read_csv("DXYNews.csv", encoding="utf_8_sig",
                         usecols=['pubDate', 'title', 'summary', 'provinceId'])
   data.to_csv("DXYNews_processed.csv", index=False, encoding="utf_8_sig")

2.读取文件,数据清洗



2. #### 提取指定数据

#根据'provinceId'参数:

#'provinceId'=42 表示湖北省

# 'provinceId'=100 表示全国

# 以此为判别依据进行数据划分。完成后分别导出CSV文件

​```python
# 判定省ID,挑选出湖北省的新闻,单独输出为表格
data_hubeiprovince = pd.DataFrame(columns=['pubDate', 'title', 'summary', 'provinceId'])
data_chanese = pd.DataFrame(columns=['pubDate', 'title', 'summary', 'provinceId'])
# 筛选湖南省和全国疫情数据
# provinceId:42表示湖北, 100表示全国
for i in range(data.shape[0]):
 if data.loc[i, 'provinceId'] == 42:
     data_hubeiprovince = data_hubeiprovince.append(data.iloc[i])
 if data.loc[i, 'provinceId'] == 100:
     data_chanese = data_chanese.append(data.iloc[i])
data_hubeiprovince.to_csv("DXYNews_hubei_province.csv", index=False, encoding="utf_8_sig")
data_chanese.to_csv("DXYNews_chanese.csv", index=False, encoding="utf_8_sig")

三、正则表达式提取每天新增确诊病例数,累计确诊病例数

匹配策略:

先按标题匹配,关键词为:新增—例,累计—例 若得到匹配结果则用,若无则按内容匹配

按内容匹配时,关键词为:“新增***确诊—例”和“累计确诊—例”或“累计新冠肺炎—例”

若标题和内容中均未匹配到结果,则表明该条新闻不包含疫情数据信息,可以舍弃。如果一条新闻中包含新增病例数或累计病例数其中一种数据的话,将未被包含的那位数置零。

代码实现如下:

# -*- coding:utf-8 -*-
import re
import pandas as pd

# 匹配策略:先按标题匹配,关键词:新增***例,累计***例
#           若有结果则用,若无结果则按内容匹配
def match(datapath, outpath):
    dataNews = pd.read_csv(datapath, encoding="utf_8_sig",
                                    usecols=['pubDate', 'title', 'summary', 'provinceId'])
    data = dataNews.reindex(columns=['pubDate', 'title', 'summary', 'provinceId', 'New', 'accumulation'])

    for i in range(data.shape[0]):
        res_new_num = 0
        res_add_num = 0
        # 新增
        res_new_title = re.search(r'新增[\u4e00-\u9fa5]*[0-9]+例', data.iat[i, 1])
        if res_new_title is not None:
            res_new_num = re.search(r'[0-9]+', res_new_title.group(0)).group(0)
        else:
            res_new_summary = re.search(r'新增[\u4e00-\u9fa5]*确诊[\u4e00-\u9fa5]*[0-9]+例', data.iat[i, 2])
            if res_new_summary is not None:
                res_new_num = re.search(r'[0-9]+', res_new_summary.group(0)).group(0)
        # 累计
        res_add_title = re.search(r'累计[\u4e00-\u9fa5]*[0-9]+例', data.iat[i, 1])
        res_add_summary = re.search(r'累计[\u4e00-\u9fa50-9,]*?[确诊|新冠肺炎][\u4e00-\u9fa5]*[0-9]+例', data.iat[i, 2])
        print(res_add_summary)
        if res_add_title is not None:
            res_class = re.search(r'累计治愈出院', res_add_title.group(0))
            # 如果不是累计出院的数据则保留
            if res_class is None:
                res_add_num = re.search(r'[0-9]+', res_add_title.group(0)).group(0)
            elif res_add_summary is not None:
                res_add = re.search(r'确诊[\u4e00-\u9fa5]*[0-9]+|新冠肺炎[\u4e00-\u9fa5]*[0-9]+', res_add_summary.group(0))
                if res_add is not None:
                    res_add_num = re.search(r'[0-9]+', res_add.group(0)).group(0)
        else:
            if res_add_summary is not None:
                res_add = re.search(r'确诊[\u4e00-\u9fa5]*[0-9]+|新冠肺炎[\u4e00-\u9fa5]*[0-9]+', res_add_summary.group(0))
                if res_add is not None:
                    res_add_num = re.search(r'[0-9]+', res_add.group(0)).group(0)
        # 数据调整
        if res_new_num != 0 or res_add_num != 0:
            data.iat[i, 4] = res_new_num
            data.iat[i, 5] = res_add_num

    data_result = data.dropna(axis=0, how='any')
    data_result.to_csv(outpath, index=False, encoding="utf_8_sig")
    return data_result

数据提取后将新数据导出到CSV文件中方便查看。

四、可视化

绘制以日期为横坐标轴的折线图

注:对累计病例来讲,匹配时由于新闻中未提及而设置为0,绘制时需要将这些为零的数据从列表中剔除。尝试了几种不同的方法后,最终使用了最便捷的函数np.isin()方法进行数据剔除。

代码实现如下:

# 绘图函数
def data_draw(data, data2, data3):
    # data
    time = [datetime.strptime(d, '%Y/%m/%d %H:%M').date() for d in data.values[:, 0]]
    plt.figure(1)
    plt.subplot(3, 2, 1)
    plt.plot(time, data.values[:, 4], 'ro-', color='r', alpha=0.8, linewidth=1)
    plt.xlabel('日期')
    plt.ylabel('全国新增人数')

    data_add = data[~data['accumulation'].isin([0])]
    time_add = [datetime.strptime(d, '%Y/%m/%d %H:%M').date() for d in data_add.values[:, 0]]
    plt.subplot(3, 2, 2)
    plt.plot(time_add, data_add.values[:, 5], 'ro-', color='r', alpha=0.8, linewidth=1)
    plt.xlabel('日期')
    plt.ylabel('全国累计人数')

    # data2
    time2 = [datetime.strptime(d, '%Y/%m/%d %H:%M').date() for d in data2.values[:, 0]]
    plt.subplot(3, 2, 3)
    plt.plot(time2, data2.values[:, 4], 'ro-', color='r', alpha=0.8, linewidth=1)
    plt.xlabel('日期')
    plt.ylabel('湖北新增人数')

    data2_add = data2[~data2['accumulation'].isin([0])]
    time2_add = [datetime.strptime(d, '%Y/%m/%d %H:%M').date() for d in data2_add.values[:, 0]]
    plt.subplot(3, 2, 4)
    plt.plot(time2_add, data2_add.values[:, 5], 'ro-', color='r', alpha=0.8, linewidth=1)
    plt.xlabel('日期')
    plt.ylabel('湖北累计人数')

    # data3
    time3 = [datetime.strptime(d, '%Y/%m/%d %H:%M').date() for d in data3.values[:, 0]]
    plt.subplot(3, 2, 5)
    plt.plot(time3, data3.values[:, 4], 'ro-', color='r', alpha=0.8, linewidth=1)
    plt.xlabel('日期')
    plt.ylabel('上海新增人数')

    data3_add = data3[~data3['accumulation'].isin([0])]
    time3_add = [datetime.strptime(d, '%Y/%m/%d %H:%M').date() for d in data3_add.values[:, 0]]
    plt.subplot(3, 2, 6)
    plt.plot(time3_add, data3_add.values[:, 5], 'ro-', color='r', alpha=0.8, linewidth=1)
    plt.xlabel('日期')
    plt.ylabel('上海累计人数')

    plt.gcf().autofmt_xdate()  # 自动旋转日期标记
    plt.show()

    
if __name__ == '__main__':
    data_chanese = match("DXYNews_chanese.csv", "match_result_chanese.csv")
    data_hubei = match("DXYNews_hubei_province.csv", "match_result_HuBei.csv")
    data_shanghai = match('DXYNews_shanghai.csv', "match_result_Shanghai.csv")
    data_draw(data_chanese, data_hubei, data_shanghai)

运行结果如下:
在这里插入图片描述

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值