Python处理疫情数据,让你的pandas跟上你的数据思维



数据来源

数据取自 github 项目 BlankerL/DXY-COVID-19-Crawler 的其中一份 csv 地区疫情统计数据,实际上这个项目只是定时到丁香园网站上爬取某个时刻的数据。

数据大致如下:

Python处理疫情数据,让你的pandas跟上你的数据思维

  • 一行记录表示,某时间点(updateTime)某地区(cityName)的各项疫情指标
  • 由于网站上显示的是当前最新累计数据,因此本数据的统计指标同样是累计数值

面对几万行多列的数据,应该先干什么呢?当然看看数据整体情况。


数据报告

我们直接使用基于 pandas 的一个快速数据报告库 pandas_profiling。如果没有安装,cmd 执行如下指令:

<code>pip install pandas_profiling
/<code>

先导入必须的包:

Python处理疫情数据,让你的pandas跟上你的数据思维

加载数据:

Python处理疫情数据,让你的pandas跟上你的数据思维

生成报告:

Python处理疫情数据,让你的pandas跟上你的数据思维

  • 我是在 jupyter notebook 上直接显示报告,你也可以输出到单独的网页文件,用浏览器打开即可查看

实际可以从报告中发现很多这份数据的问题,不过本文我们只关注"省份和城市编码的问题"。

打开"变量页面",点开"provinceName",可以看到此字段的统计信息:

Python处理疫情数据,让你的pandas跟上你的数据思维

  • 32个唯一值
  • 没有缺失数据
  • 同样的操作,我们发现字段"province_zipCode" 和 "cityName" 都没有缺失值

但是,当看到"city_zipCode" 时,却发现问题了:

Python处理疫情数据,让你的pandas跟上你的数据思维

  • 有1266个缺失值
  • 存在特殊的值,例如:-1,0

可能你会说,我们可以直接使用"cityName"做后续的数据分析需求。

如果你这么想,那么后面将会发现大坑,不管你后续的数据可视化,分析报告做得多么漂亮,源头数据都错误了,一切都白费。


城市名的问题


Python处理疫情数据,让你的pandas跟上你的数据思维


为什么不直接使用城市名字?因为城市名字是可能改变的,这源自于数据是从网站上爬取。

看看如下数据你就明白:

Python处理疫情数据,让你的pandas跟上你的数据思维

  • 可以看到,"杨浦"和"杨浦区"实际是同一个地区,名字却从某时刻开始改变了
  • 更严重的是,"杨浦"的城市编码是空的!
  • 如果使用"cityName"进行处理,结果就认为有2个区,并且数据还会翻倍(因为数据指标都是累计数)。

现在,我们应该要怀疑这里的数据是否有其他的问题。那么怎样的逻辑才能验证城市编码是正确的:

  • 同一个省的同一个城市,应该只有一个唯一编码,并且编码不为空

怎么验证?


找出有问题的数据

处理很3步:

  • 省名字+城市名+城市编码,去除重复(这是因为此数据同一个城市的数据在同一天会被记录多次)
  • 按 省名字+城市名 分组,那些组中超过1条记录的,就是有问题的记录

看看代码:

Python处理疫情数据,让你的pandas跟上你的数据思维

  • 行4:去重复
  • 行5:分组
  • 行6:取出多于1条记录的组

一看吓一跳,即使不是空的编码,竟然存在同一个名字不同编码的数据。怎么解决这个问题?


那就取出每个城市中最大的编码作为该城市的编码吧:

Python处理疫情数据,让你的pandas跟上你的数据思维

  • 行6:取出 city_zipCode 列的最大值
  • 现在结果已经是每个城市只保留一条记录了

但是,这只是解决了一半的问题,现在仍然有那些空编码的城市:

Python处理疫情数据,让你的pandas跟上你的数据思维

  • 有62行呀!


Python处理疫情数据,让你的pandas跟上你的数据思维


自动找最相似的名字

这是一个代表性的例子:

Python处理疫情数据,让你的pandas跟上你的数据思维

首先我们需要一个方法,用来判断2个文本的相似度:

Python处理疫情数据,让你的pandas跟上你的数据思维

剩下的思路就很简单了:

  • 每个存在缺失城市编码的城市,到所属省份中的每个城市名字中,进行上述的相似度输出,然后取最大的作为匹配

你打算用 Python 自己撸这个逻辑?代码多、容易错、还执行慢!

直接来看看 pandas 的解决方式:

Python处理疫情数据,让你的pandas跟上你的数据思维

  • 行2:缺失编码的行
  • 行3:存在编码的行
  • 行5:把2个表,按省份关联。关联后的结果,相当于每个缺失编码的城市与同省份的其他城市配对起来
  • 行6-8:用左表的城市名(cityName_x) 与 右表的城市名(cityName_y) 执行相似度方法 city_diff_rate
  • 行11:按 省份+缺失表的城市名 分组,取相似度最大记录的索引
  • 行12:取出记录

直接输出到 Excel 看看:

Python处理疫情数据,让你的pandas跟上你的数据思维

  • 看最右边的列,是相似度。可以看到,高相似度的行的匹配结果是对的
Python处理疫情数据,让你的pandas跟上你的数据思维

  • 而最低的几个相似度的结果中,大概只有上面红框的4行记录不知道对不对。这个后面再探究
  • 这太好了,62个缺失编码,我们只需要用手工处理5个

你可能会注意到,缺失编码的记录是62行,但我们的匹配结果是61行,这是因为 merge 的时候使用了 内连接,而那条记录是 澳门地区,他整个记录中只有一个地区,同时缺失编码


最后

关于这个城市编码补全的工作剩下的步骤:

  • 把整个省份城市编码表整理出来
  • 手工填补 4 行未知记录以及澳门地区的 1 行记录
  • 后续处理分析工作基于整理的编码表进行

下一篇,将教你怎么快速把累计数据变成每天变化数据。敬请关注!


需要源码的小伙伴请转发本文并私信我"python"

如果希望从零开始学习 pandas ,那么可以看看我的 pandas 专栏。


分享到:


相關文章: