我心目中的数据工作流程应该是这样的

我心目中的数据工作流程应该是这样的

我最近一直在想如何建立起一套高效的工作流程,而这套流程中如何高效的使用使用数据是最为关键的。经过仔细的思考,我计划建立一个下面的工作流程:

当然我还没有图中展示的那么强,图中显示的只是一个计划。未来自己将按照这一计划学习和工作。

这个流程包括数据搜集与整理、数据存储与管理、数据再处理(建模)和可视化以及最终的报告呈现四部分。在数据搜集整理方面,自己的目标是学习好所列示的几种工具。不过不同于以往的工作方式,未来自己将不会再简单搜集完数据之后就把它弄个什么文件丢在某个文件夹了,而是按照一个统一的架构存入数据库。

数据存储和管理方面,目前所希望掌握的两个数据库就是MySQL和MongoDB,因因为很多爬虫框架使用MongoDB(这是一个非关系型数据库),所以未来也一定得学习一下。

数据再处理和可视化同样是上面几门语言,除此之外自己还计划用好一些GUI绘图工具,例如Tableau(我发现任泽平的团队绘图就是使用这个,这个软件可以直接连接数据库)、OmniGraffle(绘制流程图的,上面的这个流程图就是这个软件绘制的)以及XMind(也是绘制流程图的)。在JavaScript中,希望自己能掌握ECharts、Highcharts这些图表库,还有当然要学习D3.js了。

最后就是报告呈现了。Word和PPT过于难用了,自己还是打算用好pandoc+Markdown,以及Latex。还有要用好HTML5制作幻灯片,自己发现的一个非常好的制作在线PPT的网站是:slides。比起传统的展示工具,Html5能够更加动态的展示。

作为这个流程的开篇,我打算首先改正我的网站的数据页面的数据维护方式。这个改正工作量是比较大的,今天就该了一个中美失业率比较的数据。

首先作为一个示例,我展示一下如何维护一个股票列表的数据表。

首先,下面的Stata代码可以实现创建该数据表的操作:

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
clear all
mysqlcall, s
mysqlcall "drop schema if exists stock;"
mysqlcall "create database stock;"
mysqlcall "create table stock.stock_basic_information"
mysqlcall "("
mysqlcall " number int,"
mysqlcall " code char(6) primary key,"
mysqlcall " name varchar(15),"
mysqlcall " total_stock_num float,"
mysqlcall " outstanding_stock_num float,"
mysqlcall " outstanding_stock_value float,"
mysqlcall " registered_capital float,"
mysqlcall " pe_ratio float,"
mysqlcall " industry varchar(40),"
mysqlcall " concept varchar(20),"
mysqlcall " area varchar(20),"
mysqlcall " close float"
mysqlcall ")engine = InnoDB;"
mysqlcall, e r

上面的代码只需要运行一次就够了,接下来是下载数据并将数据存到刚刚新建的表中。

Stata
1
2
3
4
5
* 下载数据
cnstock2

* 存数据
mysqlj stock stock_basic_information

如下下次想用这个数据,只需要运行下面的代码即可:

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
mysqli stock stock_basic_information, v( ///
编号 ///
股票代码 ///
公司名称 ///
总流通股本_亿股 ///
流通股本_亿股 ///
流通市值_亿元 ///
注册资本_万元 ///
市盈率 ///
所属行业 ///
所属概念 ///
所属地域 ///
收盘价)

当然凭借着强大的cnstock2命令,这一操作是浪费时间,但是如果我是在其它软件中需要这个数据呢?良好的数据维护习惯可以让你立即能读到数据,而不是先用Stata下载再把用另外一个工具把文件读过去。

这个例子就是这样的了。

然后我又按照这一原则改正了一下中美失业率对比的绘图脚本(也是Stata)。

首先是把历史数据爬好,需要注意这里在爬华尔街见闻,里面的数据接口是动态接口,所以每隔一段时间需要更换一次链接:

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
cd "~/Documents/plotdata"
cap mkdir "中美两国失业率比较"
cd "中美两国失业率比较"

/*===========================================*/
/* 爬取历史数据
/*===========================================*/

* local 城镇登记失业率 "https://wows-api.wallstreetcn.com/v3/asset/snapshot/kline?fields=ceic_code,publish_at,real,predict&ceic_codes=jX7Lcs2%2FiwNCEA%2FAOdGrRQ%3D%3D&_=1536388060&sign=78307eef15afb6da1da5fc5bd54ed23a"

* local 美国失业率 "https://wows-api.wallstreetcn.com/v3/asset/snapshot/kline?fields=ceic_code,publish_at,real,predict&ceic_codes=9LdkmdFeC3MTfUvH2r6Nug%3D%3D&_=1536388042&sign=ba8c1b0a59e2dd74d81735569e7414c1"

* !curl "`城镇登记失业率'" | tr "[" "\n" > my.txt
* infix strL v 1-20000 using my.txt, clear
* drop in 1/3
* split v, parse("," `"""')
* keep v3 v5
* destring, replace
* replace v3 = v3*1000 + tc(1 jan 1970 08:00:00)
* tostring v3, replace force format(%tCCCYY-NN-DD_HH:MM:SS)
* replace v3 = substr(v3, 1, 7)
* compress
* ren v3 月份
* ren v5 城镇登记失业率
* save 城镇登记失业率, replace

* !curl "`美国失业率'" | tr "[" "\n" > my.txt
* infix strL v 1-20000 using my.txt, clear
* drop in 1/3
* split v, parse("," `"""')
* keep v3 v5
* destring, replace
* replace v3 = v3*1000 + tc(1 jan 1970 08:00:00)
* tostring v3, replace force format(%tCCCYY-NN-DD_HH:MM:SS)
* replace v3 = substr(v3, 1, 7)
* compress
* ren v3 月份
* ren v5 美国失业率
* save 美国失业率, replace

* use 城镇登记失业率, clear
* merge 1:1 月份 using 美国失业率
* drop _m
* !rm *.txt
* !rm *.dta
* gen date = date(月份, "YM")
* gsort date
* drop date
* replace 月份 = 月份 + "-01"

我把上面的代码都注释掉了,这是因为历史数据只需要爬一次就够了,就下来只需要向数据库中添加新的数据即可。而且向华尔街见闻这种动态链接的数据,每次爬数据都要更新链接明显比只更新一个最新的数据即可。这个失业率数据中中国的数据是季度数据而美国的数据是月度数据。

接下来是创建数据表的代码:

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
/*=================================================*/
/* 创建数据库(只需运行一次)
/*=================================================*/
* mysqlcall, s
* mysqlcall "drop schema if exists international_comparsion;"
* mysqlcall "create schema international_comparsion;"
* mysqlcall "create table international_comparsion.unemployment_rate_comparsion_between_cn_us"
* mysqlcall "("
* mysqlcall " date date primary key,"
* mysqlcall " cn_registered_urban_unemployment_rate float,"
* mysqlcall " us_unemployment_rate float"
* mysqlcall ")engine = InnoDB;"
* mysqlcall, e r
* mysqlj international_comparsion unemployment_rate_comparsion_between_cn_us

注释掉的原因也是这些代码只需要运行一次即可。下面是更新数据的代码,由于手动录入比爬取更快,所以我采用了insert:

Stata
1
2
3
4
5
mysqli international_comparsion unemployment_rate_comparsion_between_cn_us, v(月份 城镇登记失业率 美国失业率)
* mysqlcall, s
* mysqlcall "insert into international_comparsion.unemployment_rate_comparsion_between_cn_us values('2018-09-01', null, 3.9)"
* mysqlcall, e r
mysqlj international_comparsion unemployment_rate_comparsion_between_cn_us

被我注释掉的部分是一个例子,以后每个月我只需要看看华尔街见闻然后把数据用注释掉的部分代码插入数据库即可。

最后,在有需要的时候,再把数据库取出来绘图,例如我使用Stata调用JavaScript代码绘制的图标(这里用的是Highcharts图表库):

Stata
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
/*============================================*/
/* 从数据库中读取数据进行绘图
/*============================================*/
mysqli international_comparsion unemployment_rate_comparsion_between_cn_us, v(月份 城镇登记失业率 美国失业率)
save 中美失业率比较, replace
export delimited using "中美失业率比较.csv", replace
export excel using "中美失业率比较.xlsx", firstrow(variables) replace

use 中美失业率比较, clear
drop in 1/624
foreach i of varlist _all{
cap replace `i' = "NaN" if `i' == "NULL"
}
tostring _all, replace format(%6.1f) force
fw, s h(中美失业率比较)
fw `"<!DOCTYPE HTML>"'
fw `"<html>"'
fw `"<head>"'
fw `" <meta charset="utf-8">"'
fw `"<meta name="viewport" content="width=device-width, initial-scale=1"> <script src="http:\/\/www.czxa.top/jslib/hc/highcharts.js"></script>"'
fw `" <script src="http:\/\/www.czxa.top/jslib/hc/exporting.js"></script>"'
fw `" <script src="http:\/\/www.czxa.top/jslib/hc/oldie.js"></script>"'
fw `" <script src="http:\/\/www.czxa.top/jslib/hc/highcharts-zh_CN.js"></script>"'
fw `" <script src="http:\/\/www.czxa.top/jslib/hc/sand-signika.js"></script>"'
fw `"</head>"'
fw `"<body>"'
fw `" <div id="container" style="min-width:600px;height:400px"></div>"'
fw `" <script>"'
fw `" var chart = Highcharts.chart('container', {"'
fw `" chart: {"'
fw `" type: 'spline'"'
fw `" },"'
fw `" title: {"'
fw `" text: '中美失业率比较'"'
fw `" },"'
fw `" subtitle: {"'
fw `" text: '数据来源:华尔街见闻'"'
fw `" },"'
fw `" xAxis: {"'
fw `" categories: ["'
forval i = 1/`=_N'{
fw `"'`=月份[`i']'',"'
}
fw `" ]"'
fw `" },"'
fw `" yAxis: {"'
fw `" title: {"'
fw `" text: '失业率'"'
fw `" },"'
fw `" labels: {"'
fw `" format: '{value}%'"'
fw `" },"'
fw `" },"'
fw `" plotOptions: {"'
fw `" spline: {"'
fw `" dataLabels: {"'
fw `" enabled: true"'
fw `" },"'
fw `" enableMouseTracking: true"'
fw `" }"'
fw `" },"'
fw `" series: ["'
fw `" {"'
fw `" name: '中国城镇登记失业率',"'
fw `" data: ["'
forval i = 1/`=_N'{
fw `"`=城镇登记失业率[`i']',"'
}
fw `"],"'
fw `" tooltip: {"'
fw `" valueSuffix: '%'"'
fw `" }"'
fw `"},"'
fw `" {"'
fw `" name: '美国失业率',"'
fw `" data: ["'
forval i = 1/`=_N'{
fw `"`=美国失业率[`i']',"'
}
fw `"],"'
fw `" tooltip: {"'
fw `" valueSuffix: '%'"'
fw `" }"'
fw `"},"'
fw `"]});</script></body></html>"'
fw, e

最后,我想把这些数据(数据页面上展示的数据)按照统一的格式命名,做成一个接口,这样就可以直接调用。

都是大工程啊!任重而道远!

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×