python医药数据分析_Python 数据分析实战,揭秘国内顶尖医院分布现状!

本文使用Python抓取春雨医生平台数据,结合地市等级划分,分析了全国顶尖医院的科室分布。数据主要涵盖全国各科室TOP10医院,发现这些医院集中在华东、华北,尤其北京、上海、广州等一线城市。数据清洗和处理后,通过Tableau进行可视化展示,指出科室维度的医疗水平情况,如北京覆盖所有科室,深圳医疗水平相对较低。分析虽不全面,但仍具参考价值。
摘要由CSDN通过智能技术生成

b0eb2b195f4301632ec235bebe60d199.png

作者 | AJ Gordon、June Alice

责编 | 屠敏

声明:本文仅作学习与交流。

在本文中,分析以“春雨医生”平台作为数据来源,通过Python抓取网站数据,结合“地市等级划分”数据,并再利用tableau制作地图和图表进行数据可视化。本文抓取的数据内容主要是全国范围内不同科室的TOP10医院名单,通过展示不同地区医院上榜的数量,以了解目前国内顶尖医疗水平的城市分布情况。由于本文采用的数据维度较少,结论仅供参考作用。

数据采集

首先,导入所需的库,再构建两个字典,一个存放地区编码,一个存放科室编码。利用两个嵌套for循环构建URL后,将全部URL存放到Redis数据库中,进行下一步操作。

import requestsfrom bs4 import BeautifulSoupimport pymysqlfrom concurrent.futures import ThreadPoolExecutor as Poolfrom redis import ConnectionPool, Redisimport warningswarnings.filterwarnings("ignore")# 地区字典area_dict = {'全国': '0','黑龙江省': '230000','吉林省': '220000','辽宁省': '210000','河南省': '410000','湖北省': '420000','湖南省': '430000','四川省': '510000','贵州省': '520000','云南省': '530000','重庆市': '500000','西藏自治区': '540000','陕西省': '610000','甘肃省': '620000','青海省': '630000','宁夏回族自治区': '640000','新疆维吾尔自治区': '650000','上海市': '310000','江苏省': '320000','浙江省': '330000','安徽省': '340000','福建省': '350000','江西省': '360000','山东省': '370000','台湾省': '710000','北京市': '110000','天津市': '120000','山西省': '130000','河北省': '140000','内蒙古自治区': '150000','广东省': '440000','广西壮族自治区': '450000','海南省': '460000','香港特别行政区': '810000','澳门特别行政区': '820000',}# 科室字典department_dict = {'妇科':'1','儿科-小儿科':'fa','儿科-新小儿科':'fb','皮肤性病科-皮肤科':'ha','皮肤性病科-性病科':'hb','内科-呼吸内科':'aa','内科-心血管内科': 'ab','内科-神经内科': 'ac','内科-消化内科': 'ad','内科-肾内科': 'ae','内科-内分泌与代谢科': 'af','内科-风湿免疫科': 'ag','内科-血液病科': 'ah','内科-感染科': 'ai','男科':'8','产科':'21','外科-胸外科':'ba','外科-心脏与血管外科': 'bb','外科-神经外科': 'bc','外科-肝胆外科': 'bd','外科-烧伤科': 'be','外科-康复科': 'bf','外科-泌尿外科': 'bg','外科-肛肠科': 'bh','外科-普外科': 'bi','外科-甲状腺乳腺外科': 'bj','中医科-中医内科':'oa','中医科-中医外科': 'ob','中医科-中医妇科': 'oc','中医科-中医男科': 'od','中医科-中医儿科': 'oe','骨伤科-脊柱科':'ca','骨伤科-关节科': 'cb','骨伤科-创伤科': 'cc','精神心理科-精神科': 'na','精神心理科-心理科':'nb','口腔颌面科':'13','眼科':'15','耳鼻咽喉科-耳科':'ja','耳鼻咽喉科-鼻科': 'jb','耳鼻咽喉科-咽喉科': 'jc','肿瘤及防治科-肿瘤内科': 'ma','肿瘤及防治科-肿瘤外科': 'mb','肿瘤及防治科-介入与放疗中心': 'mc','肿瘤及防治科-肿瘤中医科':'md','整形美容科':'16','综合':'0',}# 收集urldefget_url(): url = 'https://www.chunyuyisheng.com/pc/hospitallist/{}/{}/'for key1, value1 in area_dict.items():for key2, value2 in department_dict.items(): url_new = url.format(value1, value2) redis_db.sadd('url_hospital', url_new)returnNone

然后,访问Redis数据库读取URL,利用ThreadPoolExecutor多线程抓取。抓取过程中有几点需要注意的:首先,访问频率过快的话,会出现503编码,解决办法是先跳过,稍后再访问;其次部分页面是无数据的,如果不进行剔除,会导致抓取过程卡住不动;此外有部分页面的医院所在城市标签为None,若不进行异常处理,也会导致卡住。最后,将抓取结果存入Mysql。

# 读取URL_1defload_url_1(): crawl_url_list = redis_db.smembers('url_hospital')while len(crawl_url_list) > 0:with Pool() as executor: futures = [executor.submit(get_content_1, crawl_url) for crawl_url in crawl_url_list] crawl_url_list = redis_db.smembers('url_hospital')# 爬取Content_1defget_content_1(crawl_url): conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='XX', db='analysis_data', charset='utf8', cursorclass=pymysql.cursors.DictCursor) r = requests.get(crawl_url, headers=headers)# 由于访问频率过高会导致服务器报错503,可先跳过,稍后再访问if r.status_code==503: print(r.status_code)# 由于部分网址的医院显示为无数据,需剔除这部分网址elif'暂无数据'in r.text: print('此页无数据。。。') redis_db.srem('url_hospital', crawl_url)else: soup = BeautifulSoup(r.text, 'lxml') all_content = soup.find_all('div', {'class': 'content'})[-1]# 获取医院详情页url all_href = all_content.find_all('a') detail_url = ['https://www.chunyuyisheng.com/' + i['href'] for i in all_href]# 获取医院其它信息 content_item = all_content.find_all('div', {'class': 'content-item'})for number, content in enumerate(content_item): hospital = content.find('div', {'class': 'top-title'}).get_text().strip() position_province = content.find('div', {'class': 'right-position'}).get_text().strip().split(' ')[0]# 由于部分医院的城市标签为None,可设置为Nonetry: position_city = content.find('div', {'class': 'right-position'}).get_text().strip().split(' ')[1]except: position_city = ''# 通过值找键,返回区域和科室 area = crawl_url.split('/')[-3] department = crawl_url.split('/')[-2]defget_key(dict, value):return [k for k, v in dict.items() if v == value] area = get_key(area_dict, area)[0] department = get_key(department_dict, department)[0]# 由于部分医院的排名标签显示为None,且排名存在规律,可手工构建医院排名,保证排名字段不为空 rank = area + department + '排名第' + str(number + 1)# 构建存储列表 data = [area, department, hospital, rank, position_province, position_city,detail_url[number]]# 存入Mysqlwith conn.cursor() as cursor: sql1 = "create table if not exists `%s`(区域 varchar(255),科室 varchar(255),医院 varchar(255),排名 varchar(255),省份 varchar(255),城市 varchar(255),详细URL varchar(255)) character set utf8" % ('hospital_rank') cursor.execute(sql1) sql = "insert into hospital_rank(区域,科室,医院,排名,省份,城市,详细URL) values(%s,%s,%s,%s,%s,%s,%s)" cursor.execute(sql, data) conn.commit() print(data) redis_db.sadd('detail_url', detail_url[number]) redis_db.srem('url_hospital', crawl_url) conn.close()

4d6c486c31aa87ba299a0a355df7f0e6.png

最后,抓取详情页中的医院等级资质,步骤与上面一样,结果存入Mysql中。

# 读取URL_2defload_url_2(): crawl_url_list = redis_db.smembers('detail_url')while len(crawl_url_list) > 0:with Pool() as executor: futures = [executor.submit(get_content_2, crawl_url) for crawl_url in crawl_url_list] crawl_url_list = redis_db.smembers('detail_url')# 爬取Content_2defget_content_2(crawl_url): conn = pymysql.connect(host='localhost', port=3306, user='root', passwd='xx', db='analysis_data', charset='utf8', cursorclass=pymysql.cursors.DictCursor) r = requests.get(crawl_url, headers=headers)# 由于访问频率过高会导致服务器报错503,可先跳过,稍后再访问if r.status_code==503: print(r.status_code)else: soup = BeautifulSoup(r.text, 'lxml') hospital = soup.find('div', {'class': 'content-title'}).find('h3', {'class': 'title'}).get_text().strip() hospital_qualification = soup.find('div', {'class': 'content-title'}).find('span', {'class': 'label'}).get_text().strip()# 构建存储列表 data = [hospital, hospital_qualification]# 存入Mysqlwith conn.cursor() as cursor: sql1 = "create table if not exists `%s`(医院 varchar(255),医院资质 varchar(255)) character set utf8" % ('hospital_qualification') cursor.execute(sql1) sql = "insert into hospital_qualification(医院,医院资质) values(%s,%s)" cursor.execute(sql, data) conn.commit() print(data) redis_db.srem('detail_url', crawl_url) conn.close()

3034d7e26e0b72bebff9993d0bd99fdb.png

数据处理

数据采集后,需要对数据进行清洗。先读取采集后的医院排名和资质数据,以及地市等级划分数据,然后无用字段可以剔除掉,可拆字段需进行拆分,合并多表后的结果,需检查字段的缺失值情况,并判断是否可进行填充。最后,由于展示结果中涉及到中国地图,由于tableau将台湾归为“国家”地理编码角色,需要手工追加一行记录,以便后期作图时能显示台湾部分。

import pandas as pdpd.set_option('display.max_columns', None)pd.set_option('display.max_rows', None)# 加载数据open_filepath = 'D:\pythondata\春雨医生\excel\\{}'hospital_rank = pd.read_excel(open_filepath.format('hospital_rank.xlsx'),sheet_name='hospital_rank')hospital_qualification = pd.read_excel(open_filepath.format('hospital_qualification.xlsx'),sheet_name='hospital_qualification')city_grading = pd.read_excel(open_filepath.format('city_grading.xlsx'),sheet_name='city_grading')province_area = pd.read_excel(open_filepath.format('city_grading.xlsx'),sheet_name='province_area')# 处理数据## 剔除无用字段hospital_rank = hospital_rank.drop('详细URL',axis=1)city_grading = city_grading.drop('排名',axis=1)## 拆分字段hospital_rank['科室1'] = hospital_rank.apply(lambda x:x['科室'].split('-')[0] if'-'in x['科室'] else x['科室'],axis=1)hospital_rank['科室2'] = hospital_rank.apply(lambda x:x['科室'].split('-')[1] if'-'in x['科室'] else x['科室'],axis=1)## 合并多表result = pd.merge(hospital_rank,hospital_qualification,on='医院',how='left')result = pd.merge(result,city_grading,on='城市',how='left')result = pd.merge(result,province_area,on='省份',how='left')## 填充字段result['等级'] = result.apply(lambda x: '四/五线城市'if pd.isnull(x['等级']) else x['等级'],axis=1)##additional = pd.DataFrame({'区域':['全国'],'省份':['台湾省'],'城市':['台湾'],'地区':['华东']})result = pd.concat([additional,result])## 保存结果result.to_csv(open_filepath.format('result.csv'),index=0, encoding="utf_8_sig")

数据可视化

首先,从地区维度去看,全国不同科室TOP10医院主要集中分布在华东和华北地区,华南和华中数量也不少。再从省份维度展示,主要分布在北京和上海,广东、天津、江苏和浙江分布数量也较多。

8c7162190a7a66218edaa28e9a2613bc.png

接着,从城市维度展示,可以看出大部分顶尖医院集中分布在北京、上海和广州这三座一线城市,南京、杭州和天津等新一线城市也占比不少。值得关注的是深圳作为一线城市,上榜的医院仅有1家,或许是历史和地理上的原因,但也说明深圳的医疗水平在国内来讲算不上是顶尖的。

ebebb41288b1d172bdd790a59cba5afe.png

从整体上看,顶尖医院主要分布在一线及新一线城市,少部分在二线城市,而二线外的城市均没有分布。此外,几乎所有顶尖医院都是三级甲等医院。

bb288461ba5777dbb25a4e7c8284517d.png

最后,将维度细分到科室的话,可以看到北京医疗水平是最顶尖的,覆盖了所有科室。上海和广州的医疗水平也位列前茅。新一线城市中,成都、杭州、南京和武汉这四个城市科室覆盖情况也很丰富,单从这里看的话,可以说医疗水平远超深圳,因为深圳只有心理科一个科室上榜。济南市作为一个二线城市,顶尖科室水平也较为不错。

1862d20147caa71b7c18c93691d6df8b.png

结尾

此次分析仅从顶尖医院的数量来判断城市的医疗水平,采用的数据维度较少,分析不够全面,但科室这一维度来看,结果有一定的实践意义。例如有一鼻炎患者在深圳,就可以选择过去临近城市广州去看鼻科,因为那边有一家国内顶尖的医院,如此类推。也希望此次分析结果能帮助到有需要的人。

作者:AJ Gordon,对爬虫/机器学习/数据建模/可视化均有所涉猎的数据分析师;June Alice,在读研究僧一枚,跨行新手数据分析师。

【End】

《原力计划【第二季】- 学习力挑战》正式开始!即日起至 3月21日,千万流量支持原创作者,更有专属【勋章】等你来挑战

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值