当前位置: 首页 > article >正文

Stata应用:将数据“画”在中国地图上|Python数据分析

导读

有没有想过,我们每天刷到的财经新闻,背后那些密密麻麻的上市公司数据,其实可以变得直观又生动?只要几行代码,你就能像“神笔马良”一样,绘制出一张全中国的“上市公司热力图”,看清每个省份有多少家A股上市公司。这时,Stata的spmap 命令就能帮你把枯燥的数剧变成生动的地图,通过颜色的深浅,一眼就能看出各省份的上市公司数量分布,你还会发现哪些省份在“领跑”,哪些地区在奋起直追。这不仅是财经分析的利器,更是快速洞察中国经济格局的“地图”。今天,让我们用spmap命令,绘制出一张中国A股上市公司分布图,让数据既简单易懂,又充满趣味!

一、准备各省2023年A股上市公司数据
爬取单页信息

我们通过中商产业研究院网站获取A股上市公司数据,共有264页。首先,我们对第一页进行分析,具体网址为:https://s.askci.com/stock/a/0-0?reportTime=2024-09-30&pageNum=1#QueryCondition。右击网页查看网页源代码,找到我们需要信息的所在位置。网页信息如下图:

接下来,调用Stata获取网页内容,并将获取内容保存到指定路径,保存文件名为temp1.txt。观察获取的txt文件,选取逐行读取文件命令,删除无关信息(如脚本、样式等),筛选出 和 标签中的内容,并通过正则表达式提取 或 中的有效信息。具体代码如下:


*爬取数据前,先安装以下命令
 ssc install carryforward
 ssc install nrow
 ssc install tidy
 
*进行第一页数据爬取
clear all
cd "D:/Backup/Desktop/Stata"
copy "https://s.askci.com/stock/a/?reportTime=2023-12-31&pageNum=1" temp1.txt, replace
infix strL v 1-1000 using temp1.txt, clear
keep if index(v, "<th") | index(v, "<td")
gen temp = 1 if v == "<thead>"
carryforward temp, replace
keep if temp == 1
drop if v == "<thead>"
drop temp
replace v = ustrregexs(1) if ustrregexm(v, ">(.*)<")
replace v = ustrregexs(1) if ustrregexm(v, `"blank">(.*)</a>"')
replace v = ustrregexs(1) if ustrregexm(v, ">(.*)\(")
replace v = ustrregexs(1) if ustrregexm(v, ">(.*)")
drop if v == "公司财报"
drop if v == ""

通过提取出来的信息可以发现,每14行对应一个完整的公司信息:

所以我们可以将数据整理为结构化的表格格式,将数据按 14 行为一组进行分块处理,并将分块后的数据从长表格式(每行一条记录)转为宽表格式(每个公司占一行,字段为列)。最后只保留公司名称、省份等关键字段,将其余无关字段、重复数据删除,保存为dta文件以便后续分析。代码和结果如下:


gen id = "var" + string(mod(_n, 14))
egen group = seq(), block(14)
spread id v
drop group
duplicates drop var2,force
keep var1 var2 var3 var5
nrow 1 
save 公司数据.dta, replace

循环爬取多页信息

通过观察第一页的网址链接可以发现,“pageNum=”参数控制着网页的页码, 因此,我们可以通过修改“pageNum=”参数进行循环构造分页 URL,逐页爬取数据。例如:循环变量i从 1 到 100,意味着爬取前 100 页的 HTML 文件。将每页的数据保存为独立的文本文件,如 temp1.txt、temp2.txt……

为了提高运行的效率以及保证数据的可得性,我们每次爬取至多100页数据,分别从第2-100页、第101-201页、第202-264页进行爬取。并将每一页提取的内容合并到主数据集中,删除重复值后保存最终的dta文件。具体操作代码如下所示:


*2-100页的内容抓取
forvalues i = 2/100 {  
    copy "https://s.askci.com/stock/a/?reportTime=2023-12-31&pageNum=`i'" temp`i'.txt, replace
    infix strL v 1-1000 using temp`i'.txt, clear
    keep if index(v, "<th") | index(v, "<td")
    gen temp = 1 if v == "<thead>"
    carryforward temp, replace
    keep if temp == 1
    drop if v == "<thead>"
    drop temp
    replace v = ustrregexs(1) if ustrregexm(v, ">(.*)<")
    replace v = ustrregexs(1) if ustrregexm(v, `"blank">(.*)</a>"')
    replace v = ustrregexs(1) if ustrregexm(v, ">(.*)\(")
    replace v = ustrregexs(1) if ustrregexm(v, ">(.*)")
    drop if v == "公司财报"
    drop if v == ""
    
    gen id = "var" + string(mod(_n, 14))
    egen group = seq(), block(14)
    spread id v
    drop group
    duplicates drop var2,force
    keep var1 var2 var3 var5
    nrow 1
    gen a = `i' 
    
    append using 公司数据.dta
    save 公司数据.dta, replace
   }
   
*101-201页的内容抓取
forvalues i = 101/201{  
    copy "https://s.askci.com/stock/a/?reportTime=2023-12-31&pageNum=`i'" temp`i'.txt, replace
    infix strL v 1-1000 using temp`i'.txt, clear

    keep if index(v, "<th") | index(v, "<td")
    gen temp = 1 if v == "<thead>"
    carryforward temp, replace
    keep if temp == 1
    drop if v == "<thead>"
    drop temp
    replace v = ustrregexs(1) if ustrregexm(v, ">(.*)<")
    replace v = ustrregexs(1) if ustrregexm(v, `"blank">(.*)</a>"')
    replace v = ustrregexs(1) if ustrregexm(v, ">(.*)\(")
    replace v = ustrregexs(1) if ustrregexm(v, ">(.*)")
    drop if v == "公司财报"
    drop if v == ""

    gen id = "var" + string(mod(_n, 14))  //转换表格格式
    egen group = seq(), block(14)
    spread id v
    drop group
    duplicates drop var2,force
    keep var1 var2 var3 var5
    nrow 1 
    gen a = `i'

    append using 公司数据.dta
    save 公司数据.dta, replace
   }

*202-264页的内容抓取   
forvalues i = 202/264{  
  
    copy "https://s.askci.com/stock/a/?reportTime=2023-12-31&pageNum=`i'" temp`i'.txt, replace
    infix strL v 1-1000 using temp`i'.txt, clear

    keep if index(v, "<th") | index(v, "<td")
    gen temp = 1 if v == "<thead>"
    carryforward temp, replace
    keep if temp == 1
    drop if v == "<thead>"
    drop temp
    replace v = ustrregexs(1) if ustrregexm(v, ">(.*)<")
    replace v = ustrregexs(1) if ustrregexm(v, `"blank">(.*)</a>"')
    replace v = ustrregexs(1) if ustrregexm(v, ">(.*)\(")
    replace v = ustrregexs(1) if ustrregexm(v, ">(.*)")
    drop if v == "公司财报"
    drop if v == ""

    gen id = "var" + string(mod(_n, 14))
    egen group = seq(), block(14)
    spread id v
    drop group
    duplicates drop var2,force
    keep var1 var2 var3 var5
    nrow 1 
    gen a = `i'

    append using 公司数据.dta
    save 公司数据.dta, replace
   }

计算各省份上市公司数量

得到全部的公司以及所在省份数据后,按照省份进行分组,计算每个省份的上市公司数量,删除重复的省份记录,确保每个省份只有一条数据,生成一个按省份统计的上市公司数量结果,得到可以和地理数据匹配的数据(除港澳台),保存为完整数据.dta文件,便于后续可视化使用。


duplicates drop 股票代码,force
gen num = 1 
drop if  省份=="--"
bys 省份:egen num1 = total(num)
sort 省份
drop if num1 == 1
keep 省份 num1
duplicates drop 省份 num1,force
gen merged_region = 省份  //统一省份名称格式
replace merged_region = "上海" if 省份 == "上海市"
replace merged_region = "北京" if 省份 == "北京市"
replace merged_region = "江苏" if 省份 == "南京市"
replace merged_region = "江苏" if 省份 == "苏州市"
replace merged_region = "福建" if 省份 == "厦门市"
replace merged_region = "浙江" if 省份 == "台州市"
replace merged_region = "安徽" if 省份 == "合肥市"
replace merged_region = "浙江" if 省份 == "宁波市"
replace merged_region = "广东" if 省份 == "深圳市"
collapse (sum) num1, by(merged_region)
rename merged_region name
rename num1 total 
save 完整数据,replace

整理后的部分数据如下:

二、准备地理数据进行合并

拿到了2023年全国各省份的上市公司数据以后,我们还需要一份包含省级边界的地理数据集,并将两者合并。

首先从阿里云下载一份中国地图数据,这里包含两份文件,分别是中华人民共和国.dta和中华人民共和国_shp.dta文件。中华人民共和国.dta是包含中国各省份名称以及经纬度的文件,中华人民共和国_shp.dta是包含各省份边界信息,用来展示出各省份在地图上形状的文件。中华人民共和国_shp.dta的数据就相当于一块画布,中华人民共和国.dta的数据就是在这块画布上面描点。

然后,我们需要将中华人民共和国.dta与当前的全国A股上市公司数据进行合并后保存。代码操作如下:


use 中华人民共和国.dta, clear
replace name = subinstr(name, "市", "", .)
replace name = subinstr(name, "省", "", .)
replace name = subinstr(name, "自治区", "", .)
replace name = "新疆" if name == "新疆维吾尔"
replace name = "广西" if name == "广西壮族"
replace name = "宁夏" if name == "宁夏回族"
sort name
ssc install spmap
merge 1:1 name using 完整数据.dta
spmap total using 中华人民共和国_shp.dta, /// 
        id(_ID)   clmethod(custom) ///
    clbreaks(0 50 100 250 400 600 800 1000) label(label(name) xcoord(_CX) ycoord(_CY) size(*.66)) ndfcolor(white)  fcolor(Blues) legstyle(2) title("2023年中国境内上市A股省份分布") note("数据来源:中商产业研究院")
graph export "2023年中国境内上市A股省份分布.png", as(png) replace

合并后的部分数据如下图所示:

三、绘制全国A股上市公司分布热力图

接下来,我们就可以利用spmap命令中的一些选项设置地图的颜色,分组,标题,比例尺等格式。

spmap total using 中华人民共和国_shp.dta, /// 
        id(_ID)   clmethod(custom) ///
    clbreaks(0 50 100 250 400 600 800 1000) label(label(name) xcoord(_CX) ycoord(_CY) size(*.66)) ndfcolor(white)  fcolor(Blues) legstyle(2) title("2023年中国境内上市A股省份分布") note("数据来源:中商产业研究院")

其中:total就是我们要显示在地图上的变量,表示每个省份的A股上市公司数量;id(_ID)是将地理信息与统计数据进行匹配,每个省份都有唯一的ID,通过它将地理信息与相应省份的数据连接;clmethod(custom)指定颜色分类方法,表示将根据自定义的区间来对变量total进行分段显示;clbreaks(0 50 100 250 400 600 800 1000)自定义区间。将total变量分为0到50,50到100,100到250等区间。每个区间将用不同的颜色显示,区间的划分取决于各省上市公司数量的分布;label(label(name)是为地图中的每个省份添加标签,其中name是省份名称;xcoord(_CX) ycoord(_CY):是指定标签的 X 和 Y 坐标,通常shp文件包含每个省份的中心坐标,这里_CX和_CY是中心坐标的变量;size(*.66):设置标签字体大小为原来的 66%,即缩小标签文本的大小;ndfcolor(bleaks)和fcolor(Blues)主要是用来填充颜色,对无数据的区域和其他区域分别填充不同颜色。

除此之外,对图例、标题和数据来源进行相应说明。最终生成的地图将会显示每个省份的上市公司数量,较多的省份颜色较深,较少的省份颜色较浅,便于直观展示数据的地理分布。最后我们可以用graph export命令把绘制的地图保存为图片形式:

graph export "2023年中国境内上市A股省份分布.png", as(png) replace

如上分布图所示,我们可以更直观的看到不同省份的上市公司分布情况。按照上述方法,我们也可以获取其他数据并展示在地图上,不妨试试吧。(注:涉及数据仅用于学术研究)

 python入门虽然简单,很多新手依然卡在基础安装阶段,大部分教程对一些基础内容都是一带而过,好多新手朋友,对一些基础知识常常一知半解,需要在网上查询很久。

扎实的基础知识,对之后的学习、工作都是非常必要的。从这400集的Python视频教程中由易到难,平常所有的疑难点都可以从中找到答案(比培训机构讲的都详细)。另外还配套Python中文手册这最基础的编程环境搭建就做了200多页的详细讲解!其他基础语法、函数、模块和包均一一精细解答。新手必备!

还分享Python 50G大礼包,里面还有Python面试真题,里面干货满满,一次全拿走!

01,Python大礼包

02,Python电子书

03,Python面试集锦

04

Python小白必备手册

05,Python安装包

06,数据分析全套资源

这只是冰山一角,想要完整版的小伙伴下图获取~


在这里插入图片描述


http://www.kler.cn/a/511630.html

相关文章:

  • redis性能优化参考——筑梦之路
  • 华为HuaweiCloudStack(一)介绍与架构
  • 【Linux系统编程】—— 深度解析进程等待与终止:系统高效运行的关键
  • Spring Boot 集成 MongoDB:启动即注入的便捷实践
  • ChatGPT 写作系列
  • 计算机网络-数据链路层
  • springboot财务管理系统
  • Unity3D仿星露谷物语开发24之创建时间管理器
  • 【Kafka】Linux+KRaft集群部署指南
  • 在 Ubuntu 上安装 Jetzig 框架指南
  • 【Java数据结构】优先级队列(堆)
  • KubeSphere 与 Pig 微服务平台的整合与优化:全流程容器化部署实践
  • ChatGPT 写作系列
  • 汇编与逆向(一)-汇编工具简介
  • 【24】Word:小郑-准考证❗
  • Windows 通过 openssh 连接 Ubuntu 24.04 LTS
  • leetcode300.最长递增子序列
  • css‘s hover VS mobile
  • UnderTow服务器
  • 第10章:Python TDD优化货币类方法与引入工厂方法
  • 【学习笔记15】如何在非root服务器中,安装属于自己的redis
  • rocketmq dashboard 安装
  • w-form-select.vue(自定义下拉框组件)
  • 1.写在前面
  • 【无标题】Cloudlog 电台日志系统 request_form SQL注入漏洞复现
  • Linux自学指南(学习路线大纲)