[QGIS教學系列]類別分析(Categorical Analysis)教學-以超商分布地圖為例

#GIS #QGIS # #類別分析 #Categorical Analysis #主題地圖 #超商地圖

*(2023/09/28) 新增練習檔案

https://drive.google.com/file/d/1PY5fYnhagnoAXzY6vVf15Vu5d4XezqwA/view?usp=sharing

[QGIS教學系列]類別分析(Categorical Analysis)教學-以超商分布地圖為例

超商地圖資料群組分析

這篇教學主要分享一以下我在製作超商分布地圖時,對於在QGIS中進行類別分析踩到的坑以及對應的解決方式,並簡單說明以下製作超商地圖的流程對於該地圖成果有興趣的話可以點擊下方連結

超商品牌分布地圖

1.四大超商資料準備以及清洗

四大超商均有自己的門市查詢頁面,相關連結我放在成果文章當中,對於四大超商門市資料我這邊提供三個資料抓取的管道

1.1 全國商工行政服務入口網

全國商工行政服務入口網
全國商工行政服務入口網

若超商門市採用「分公司模式」進行登記,我們則可以藉由查詢超商名稱,並藉由分公司資料進行查詢

全國商工行政服務入口網資料查詢介面
全國商工行政服務入口網資料查詢介面
統一超商分公司
統一超商分公司

該網站雖然沒有提供資料下載,但有提供資料查詢介接的API服務,可以透過簡易的爬蟲進行多筆資料的查詢,可以參考以下影片。

Python爬蟲|API介接之教學

1.2 根據四大超商各自的網頁進行爬蟲(筆者採用此方法)

上述的查詢方式適用於依照分公司模式登記資料時較為方便,但現實情況下許多設立連鎖門市的店舖並沒有分公司資料可以進行查詢,因此如果該公司有提供門市查詢的頁面時,採用爬蟲進行資料抓取整理是一個較為通用的方法,其中筆者推薦採用Python語言中的 request+bs4 或是 selenium進行網頁爬蟲。

2. 地址轉換經緯度

大部分爬取出來的門市資料,都是以店舖的地址為主,少部分會額外提供經緯度資料,因此需要針對地址資料轉換成經緯度坐標,方便後續匯入QGIS進行分析,對於大量地址轉換經緯度可以參考我以前撰寫的兩篇文章。

3. 超商資料進行類別分析

這小節會介紹QGIS中或外部輔助進行群組分析的工具,簡介用法還有使用時機

3.1 Join功能加入鄉鎮資料

由於要統計出各鄉鎮市區數量最多的超商品牌,因此必須以「行政區」為單位針對各超商品牌的數量進行統計,一般來說我們爬蟲出來的資料會有地址,根據地址可以藉由Excel或分割出「縣市」、「鄉鎮」、「村里」等資料作為分析依據,但由於上一步驟中已經將地址額外轉換成經緯度資訊了,因此也可以利用空間查詢的方式將店鋪位置所在的區域將行政區域圖中的村里加入到店鋪點位資料當中

藉由地址區分出行政區單位
類別分析(Categorical Analysis)教學
藉由地址區分出行政區單位
Join by location 將 villagecode(村里表示碼) 加入全家點位資料
類別分析(Categorical Analysis)教學
Join by location 將 villagecode(村里表示碼) 加入全家點位資料
行政區資料成功加入超商資料
類別分析(Categorical Analysis)教學
行政區資料成功加入超商資料
類別分析(Categorical Analysis)教學
資料合併功能(Merge vector layer)

同樣的步驟我們可以先將所有超商資料進行利用上圖合併後執行一次Join操作即可,合併後的資料會將所有欄位進行合併,若沒有對應欄位則資料會空白,我們可以藉由「Layer」欄位判斷該筆資料來自哪個原始圖層,同時也是後續的分組統計依據之一。

觀察下圖執行Join操作後的成果可以發現,同樣的VILLCODE(村里行政區)擁有多筆不同的超商資料,下一個步驟則是要將行政區作為類別,統計出各區域中佔比最大的超商品牌為何。

layer表示該筆資料的來源圖層
類別分析(Categorical Analysis)教學
layer表示該筆資料的來源圖層
執行Join操作後資料成果-
類別分析(Categorical Analysis)教學
執行Join操作後資料成果

3.2 QGIS中的類別分析(Statistics by categories)[有限制]

QGIS本身有提供依照類別進行統計的功能,但該功能僅適用於數字資料類型,例如針對行政區域進行面積、人口等數量進行加總統計,但對於字串資料(String),雖然該功能同樣能進行分析,但只有部分欄位能進行參考,例如下圖以行政區作為類別統計「Layer」欄位的數據,其中Count、Unique分別可以提供商店的總數以及種類數,但其統計出來的Max、Min值,對於字串形態會統計string_length進行比較,回傳長度較長的字串為true,若比較字串以及「包含數字、特殊符號的字串」,則會依照純字串回傳true。

Statistics by categories-
類別分析(Categorical Analysis)教學

雖然 [全家] 的字串長度為2,[711]為3,但受限於運算規則還是會回傳[全家]作為true,同時該功能回傳的欄位是固定的,無法計算各行政區域中數量最多的品牌並進行回傳。

QGIS運算中字串比較結果
QGIS運算中字串比較結果

3.3 Group Stats、ProcessX外掛進行群組分析

QGIS中有一款用於群組統計的外掛套件稱為[GroupStats],其用法相似於Excel、Google sheet的樞紐分析,可以針對不同欄位進行設定統計數量、總和、平均等。

透過Plugin頁面進行Group Stats安裝
-類別分析(Categorical Analysis)教學
透過Plugin頁面進行Group Stats安裝

QGIS中有一款用於群組統計的外掛套件稱為[GroupStats],其用法相似於Excel、Google sheet的樞紐分析,可以針對不同欄位進行設定統計數量、總和、平均等。例如我們可以將[Villcode]作為ROW、[Layer]作為Columns項,值則選擇[Count]、[Layer],這樣可以統計出各行政區中不同超商的數量,但如果要進行數量排序還需要額外整理。

GroupStats統計各行政區超商數量
-類別分析(Categorical Analysis)教學
GroupStats統計各行政區超商數量

要達到同樣的欄位統計還可以安裝[Processx]外掛,其速度更快同時包含了Join步驟,因此可以節省一個資料處理的步驟,也提供不同種類的回傳格式。

ProcessX安裝頁面
ProcessX安裝頁面

這邊採用Count Features in Features by Category功能,由於該功能直接包含了join by location功能,因此我們只要選擇要行政區圖(Village_NLSC)、超商點位圖(Merged),然後以[Layer]作為類別進行分析,回傳格式則選擇「針對每一個類別新建一個欄位」

Count Features in Features by Category
-類別分析(Categorical Analysis)教學
Count Features in Features by Category

執行結果如下圖,其回傳的圖層是加入統計資料後的村里圖資,其中資料統計出來全家、ok、711各有一間,對照點位圖也是同樣的結果。

3.4 Google Sheet 樞紐分析表群組分析

雖然Group Stats可以做到類似Google Sheet的樞紐分析功能,但自由度還是比不上直接使用Excel或是Google Sheet,這時候我們可以直接複製QGIS表格中的資料直接貼上Google sheet進行分析(資料量小時適合),搭配額外的公式撰寫可以篩選出各行政區中最多數量的超商品牌。

這邊採用Google Sheet的樞紐分析,搭配Max()、XLookup()函數,先將各品牌超商數量進行統計後,比較數量最多的超商後將超商品牌進行回傳,即可找到該村裡的優勢超商,但以下示範公式若遇到各品牌超商數量相同時,只會回傳第一筆配對成功的資料,會造成部分區域失真。

Google sheet 樞紐分析搭配公式查詢數量最多的超商
Google sheet 樞紐分析搭配公式查詢數量最多的超商

3.5 QGIS-SQL語法進行群組分析(自由度高、功能強大)

QGIS本身也提供了基於SQL結構化查詢,其中SQL可以設定多條件來解決上述提到的各品牌數量相同時計算錯誤的問題,對於SQL的相關功能使用可以從功能表中的Database->DB manager中進行使用。

DB Manager
DB Manager
DB manager頁面
DB manager頁面
SQL查詢頁面

接著採用以下語法進行查詢,依照個人理解進行註釋,有錯誤的話歡迎留言告知!

WITH LayerCounts AS (
  SELECT VILLCODE,
		 geometry,
         layer,
         COUNT(*) AS layer_count, --計算同villcode-layer組中 有幾筆資料
         DENSE_RANK() OVER (PARTITION BY VILLCODE ORDER BY COUNT(*) DESC) AS rn --透過VILLCODE進行分組,依照layer_count進行排序
    FROM 超商合併_Villcode --來源表
  GROUP BY VILLCODE,layer --透過VILLCODE,layer分組
)

SELECT 	
    VILLCODE,
		rn,
    layer,
		SUM(layer_count) AS layer_count, 
		geometry,
       CASE
           WHEN COUNT(DISTINCT layer) = 1 Then layer  --組內超商品牌都相同的話 該品牌為優勢品牌
           WHEN (COUNT(DISTINCT layer))!=1 AND (COUNT(DISTINCT rn) = 1) THEN '中立'  --組內超商品牌不同且排名都是1都話(代表店數一樣),表示中立
           ELSE layer --反之回傳排序1作為優勢品牌
       END AS 優勢品牌
  FROM LayerCounts
GROUP BY VILLCODE
SQL回傳結果
SQL回傳結果

SQL查詢後的結果還提供[Load as new layer]功能,能夠直接匯入回QGIS中(需引入空間資料欄位)後按下[Load]即可匯入QGIS,並透過Join by fields功能利用Villcode就可以將優勢品牌資料加入給鄉鎮市區圖進行分類

[Load as new layer]功能
[Load as new layer]功能

4 參考資料

Documentation for QGIS 3.28 — QGIS Documentation documentation

5 更多教學

分享