在Pandas可以使用groupby
等方法進行資料聚合
例如先前第三天的路燈資料,如果想看一下不同的統計成果,除了空間上的展示外,可以用資料內的行政區欄位(district)做聚合
回顧這份資料,有district欄位表示行政區
1 | light=gpd.read_file('output/light.shp',encoding='utf-8') |
我們可以很簡單的用groupy做資料的的聚合1
light.groupby('district').size()
如果資料中沒有這樣的屬性呢?(例如第三天的另一份圖書館點為資料)
在GIS資料中,我們可以對資料做空間聚合,聚合的單元可以是面資料。
路燈及圖書館資料請參考及Day03 從Pandas到Geopandas的幾種方法
spatial join
首先我們下載村里界圖
新北市政府資料開放平台,試著把圖書館資料與其做連結
把村里界圖讀進來,稍作觀察1
2
3
4import geopandas as gpd
village=gpd.read_file('data/Village/Village.shp',encoding='utf-8')
village.crs= {'init' :'epsg:3826'} # 避免資料沒設,這邊再重新給一次
village.head(3)
可以看出來ADMIV及ADMIT是村里與行政區
把圖書館資料有讀進來1
2
3
4lib=gpd.read_file('output/library.shp',encoding='utf-8')
lib.crs= {'init' :'epsg:4326'} # 避免資料沒設,這邊再重新給一次
lib=lib.to_crs(epsg=3826)
lib.head(3)
從上面可以看到,這份圖書館沒有行政區的資訊,無法直接產出如前面的統計表,但是由於我們有村里的GIS資料,可利用資料間的空間關係整合,在此特別在提醒,請記得轉換空間坐標,讓兩者系統一致喔。
坐標轉換請參考前一天的文章: Day04 幾何資料基本運算
先把他們套疊
(ps.為了方便顯示,只選擇中和區
)1
2base=village[village['ADMIT']=='中和區'].plot(color='yellow')
lib[lib['address'].str.contains('中和區')].plot(ax=base)
從上得知,我們應該可以從空間關係取得我們要的東西,使用的是spatial join(sjoin)1
2result = gpd.tools.sjoin(lib, village[['ADMIV','ADMIT','geometry']], how="left")
result
其中,how
是選擇要left join或是right, inner join,op則是空間關聯的方法,有contains
, within
, intersects
可以選擇,我們選within,因為我們想計算點被包含在哪些村里界中
spatial join完成後,我們就可以做groupy,達到前面的效果1
2group=result.groupby(['ADMIT','ADMIV'])
group.size().reset_index(name='counts')
除了表格的展示,可以展點在圖上,並以行政區做上色1
result.plot('ADMIT')
然而,如果要以地圖展示的話,可能不夠清楚,把村里的圖也納進來一起顯示吧!
aggregation
為了產生這樣的資訊,可以先計算village
圖層涵蓋到的點數量,這之中會參考到昨天的幾何基本運算,這邊使用intersects
,計算counts
,也就是包含的點數量。
1 | import numpy as np |
展示一下,並以count上色1
aggre_v.plot('count')
dissolve
試著再把資料做一次聚合,使用行政區上色,會用到dissolve
,其中第一個參數是要dissolve的欄位,aggfunc則是欄位中被合併的資料呈現的方式,我們這邊的聚合方式當然是sum
1 | dis=aggre_v.dissolve('ADMIT',aggfunc='sum') |
最後,展示成果
後記
今天的練習在QGIS等軟體都可以很方便做到,在Geopandas中,也是透過幾行程式碼就可以操作到這些效果,並且更具彈性。
今天的相關測試可以參考GitHub