在工作中,我們經常會用到全國行政區(qū)劃的信息,但我們往往只能從百度文庫或其他網站去下載別人整理過的二手資料。這些資料不一定準確,而且最重要的是不一定保持最新,有時候會給我們工作帶來意想不到的麻煩。
那怎么辦呢?其實國家民政部的網站上就提供了最新的行政區(qū)劃信息。比如我們可以得到2018年10月全國最新的行政區(qū)劃信息:
點開后,顯示的是這樣的頁面:
可以看到,這個列表雖然是全國最新的行政區(qū)劃,但我們并沒法直接使用——因為沒有顯示出省市縣的層級來。
我們需要的是一個有層級的行政區(qū)劃表:
也就是說,我們對行政區(qū)劃產生了兩個需求:
一是能夠即時獲得最新信息;二是這些信息已組織好能夠直接使用。
怎么實現(xiàn)這兩個需求呢?
我還是祭出微軟的個人自助式BI神器——PowerBI。
建立一個來自于Web的查詢
打開PowerBI Desktop(excel也行,操作邏輯都是一樣的),新建一個基于Web的查詢:
比如2018年10月份最新的行政區(qū)劃信息所在的網頁鏈接是:
http://www.mca.gov.cn/article/sj/xzqh/2018/201804-12/20181011221630.html,如下圖所示,將這個鏈接填入URL下的方框內,點擊確定:
民政部的網站很貼心,給出的行政區(qū)劃信息是一個表格,PowerBI Desktop能完整識別這類html表格:
上圖中那個Table0就是我們需要的信息。點擊確定后加載,對信息進行處理。
數據清洗和處理
上面步驟獲得的行政區(qū)劃信息包含不相干數據,我們需要將這些不相干數據過濾掉。
首先第一行的“2018年10月中華人民共和國…”我們不需要,利用“刪除最前面幾行”命令刪除第一行:
第二步是提升標題:
第三步是刪除其他不需要的列,只保留“行政區(qū)劃代碼”和“單位名稱”兩列:
處理完后的表格只剩兩列:
這時我們要進一步檢測表格是不是還有其他沒剔除的噪音信息——主要是不需要的文本信息。
第四步,將“行政區(qū)劃代碼”的格式改為整數,這樣如果這一列有不需要的文本信息,那么就會報錯,我們再把出錯的行刪除就ok了。
第五步,確認噪音信息被剔除后,再把“行政區(qū)劃代碼”格式改回為文本。這樣做的目的是避免后面統(tǒng)計時這些代碼被當成數字自動進行求和運算。我們不需要求和。
第六步,分別添加省市兩級的列。我是根據行政區(qū)劃代碼最后幾位的數字來判斷省市的。如果最后四位都是0,那么是省一級;如果最后兩位都是0,那么是市一級別:
= Table.AddColumn(#"Changed Type1", "省級", each if Text.End([行政區(qū)劃代碼],4)="0000" then [單位名稱] else null) = Table.AddColumn(#"Added Custom", "地級", each if Text.End([行政區(qū)劃代碼],2)="00" then [單位名稱] else null)
第七步:向下填充。在上一步分別添加了省市兩個級別后,我們需要把null值用對應的省或市來填充掉,因此,選擇省市兩列,右鍵,選擇“填充”——“向下”:
下面是填充后的結果:
到這一步基本就結束了。
不過我個人是強迫癥,我還想統(tǒng)計各級單位的個數。于是有了下面的內容。
統(tǒng)計匯總
這個動作其實是多此一舉,因為民政局的網站上已經有了現(xiàn)成的統(tǒng)計結果,而且細致到鄉(xiāng)、街道。
但這畢竟是2017年的數據,沒有2018年最新的數據,不是么?所以,我想自己統(tǒng)計下截止到現(xiàn)在,中國有多少個市、多少個縣。
觀察之前處理的結果,我們可以發(fā)現(xiàn)“單位名稱”里邊包含了省級單位名稱和市級單位名稱,但我們后面兩列已經有省市兩級的名稱了,所以,我們需要從“單位名稱”里剔除省市名稱,只保留縣級單位名稱即可。
于是我寫了個公式:
= Table.SelectRows(#"Sorted Rows", each not Text.EndsWith([行政區(qū)劃代碼], "0000") and not Text.EndsWith([行政區(qū)劃代碼], "00"))
但這個公式有一個大問題:它會把沒有下級單位的省級單位也過濾了,這就會導致計算省級單位的時候出錯(變成31個)。
所以我又寫了第二個公式:
= Table.SelectRows(#"Sorted Rows", each not Text.EndsWith([行政區(qū)劃代碼], "0000") and not Text.EndsWith([行政區(qū)劃代碼], "00")or Text.StartsWith([行政區(qū)劃代碼], "7") or Text.StartsWith([行政區(qū)劃代碼], "8"))
這樣沒下級單位的省級單位就保留了。但這樣帶來的后遺癥是它們依然會出現(xiàn)在”單位名稱“列和”市“一級單位名稱里。那對市縣進行計數的時候怎么剔除這類特殊區(qū)域呢?
辦法是留到統(tǒng)計時候篩選。這時又有兩種辦法。
最簡單最偷懶的辦法是直接在視覺篩選器里單獨篩選這類特殊區(qū)域:
但這樣的法子很容易導致問題:在將來的計算中忘記剔除這些特殊區(qū)域了。
所以,最保險的法子是建立度量值,在度量值里邊進行篩選:
縣計數 = CALCULATE(COUNTA('行政區(qū)劃'[行政區(qū)劃代碼]),FILTER('行政區(qū)劃',[縣級]<>"臺灣省"&&[縣級]<>"香港特別行政區(qū)"&&[縣級]<>"澳門特別行政區(qū)")) 市計數 = CALCULATE(DISTINCTCOUNT('行政區(qū)劃'[地級]),FILTER('行政區(qū)劃',[地級]<>"臺灣省"&&[地級]<>"香港特別行政區(qū)"&&[地級]<>"澳門特別行政區(qū)"))
最后獲得的統(tǒng)計結果如下:
全國目前有34個省級行政區(qū),337個地級單位,2852個縣級單位。
四川的地級單位最多,有21個;縣級單位也最多,有183個。原來海南省只有3個地級單位,寧夏有5個,西藏有7個,青海有8個,吉林、福建和貴州有9個地級單位。這些我都還是第一次才知道,看來上學時候地理沒學好。
結語
以后要獲取全國最新的行政區(qū)劃信息,只需要打開這個pbix文件,刷新即可,所有需要的信息會在一分鐘以內更新完畢。excel同理。
有興趣的小伙伴可以發(fā)私信消息”行政區(qū)劃“,我將我做的這個pbix文件發(fā)您。其實比較簡單,建議自己動手試試看。
帖子有點長,主要是步驟寫得比較詳細,謝謝閱讀。
PowerQuery部分的全部代碼如下:
let
Source = Web.Page(Web.Contents("http://www.mca.gov.cn/article/sj/xzqh/2018/201804-12/20181011221630.html")),
Data0 = Source{0}[Data],
#"Removed Top Rows" = Table.Skip(Data0,1),
#"Promoted Headers" = Table.PromoteHeaders(#"Removed Top Rows", [PromoteAllScalars=true]),
#"Removed Other Columns" = Table.SelectColumns(#"Promoted Headers",{"行政區(qū)劃代碼", "單位名稱"}),
#"Changed Type" = Table.TransformColumnTypes(#"Removed Other Columns",{{"行政區(qū)劃代碼", Int64.Type}}),
#"Removed Errors" = Table.RemoveRowsWithErrors(#"Changed Type", {"行政區(qū)劃代碼"}),
#"Changed Type1" = Table.TransformColumnTypes(#"Removed Errors",{{"行政區(qū)劃代碼", type text}}),
#"Added Custom" = Table.AddColumn(#"Changed Type1", "省級", each if Text.End([行政區(qū)劃代碼],4)="0000" then [單位名稱] else null),
#"Added Custom1" = Table.AddColumn(#"Added Custom", "地級", each if Text.End([行政區(qū)劃代碼],2)="00" then [單位名稱] else null),
#"Filled Down" = Table.FillDown(#"Added Custom1",{"省級", "地級"}),
#"Sorted Rows" = Table.Sort(#"Filled Down",{{"行政區(qū)劃代碼", Order.Descending}}),
#"Filtered Rows" = Table.SelectRows(#"Sorted Rows", each not Text.EndsWith([行政區(qū)劃代碼], "0000") and not Text.EndsWith([行政區(qū)劃代碼], "00")or Text.StartsWith([行政區(qū)劃代碼], "7") or Text.StartsWith([行政區(qū)劃代碼], "8")),
#"Renamed Columns" = Table.RenameColumns(#"Filtered Rows",{{"單位名稱", "縣級"}}),
#"Reordered Columns" = Table.ReorderColumns(#"Renamed Columns",{"行政區(qū)劃代碼", "縣級", "地級", "省級"})
in
#"Reordered Columns"