鐵人賽2019 Day03 從Pandas到Geopandas的幾種方法

  1. 1. 用Pandas讀取csv或Excel
  2. 2. DataFrame轉為Geodataframe
  3. 3. Geocoding

Geopandas可以讀取各GIS格式進行空間運算,
然而實際上我們可能拿到的資料不見得是GIS的格式

不是GIS格式,但它可能是有坐標資訊的資料

比較常見的會是一個csv,Excel含有經緯度或xy的資料,對於這樣的資料,我們可以把它轉為GeopandasGeoDataFrame

用Pandas讀取csv或Excel

為了今天的範例,我們下載[新北市路燈資料],下載該數據的csv檔,命名為Light.csv
第一步先使用Pandas讀取csv為DataFrame

1
2
import pandas as pd 
df=pd.read_csv('data/Light/Light.csv',encoding='utf-8')

ps.如果沒有pandas請記得安裝

1
conda install pandas

瀏覽一下這份資料可以看到這份資料具有TWD97X, TWD97Y坐標欄位。
接下來,我們試著把X,Y轉換成GeoDataFrame

DataFrame轉為Geodataframe

前一天提到GeoDataFrame包含geometry的屬性,
因此,要產生GeoDataFrame,需要產生geometry
這時候需要用shapely套件中的geometry
我們使用之中的Point類型,並把TWD97X, TWD97Y包成geom

1
2
3
from shapely.geometry import Point
import geopandas as gpd
geom = [Point(xy) for xy in zip(df.TWD97X, df.TWD97Y)]

有了geom,我們可以用來產生GeoDataFrame
其中,需要指定crs,由於TWD97X, TWD97Y的坐標是TWD97,為epsg:3826

[Day10] 坐標系統及WebGIS常用的坐標轉換

1
2
3
crs = {'init': 'epsg:3826'}
gdf = gpd.GeoDataFrame(df, crs=crs, geometry=geom)
gdf

就這樣,我們成功把csv轉成了GeoDataFrame,
然後我們就可以做GeoDataFrame能做的事
把永和區的資料畫圖來,並以address為color code繪圖,

1
gdf[gdf['district']=='永和區'].plot(column='address')

Screen Shot 2018-10-17 at 21.07.31.png

Geocoding

像是今天的資料集[新北市路燈資料]是一個具有XY的資料,
如果今天資料中沒有XY,我們還是可以透過一些Geocoding方法取得坐標
[Day 9] 自己產製資料-地址定位part2提到可以使用TGOS來進行門牌地址的Geocoding。

為了一次性的完成Geocoding,接下來以TomTom Developer Portal Geocode的Geocoding為例(個人經驗是會有較好的成果)

首先,必須要取得一個api key,方法很簡單,按照官網方法操作就好User account | TomTom Developer Portal

假設以順利取得api的key,我們現在以新北市各圖書館地址電話表為範例,下載csv使用

首先,跟上面一樣,用Pandas讀取csv

1
2
3
import pandas as pd 
df=pd.read_csv('data/Library/Library.csv',encoding='utf-8')
df

接著我們寫一個函式處理Geocoding,呼叫的方法及回應的格式直接參考TomTom Developer Portal Geocode的說明

其中,YOUR_KEY必須填入你的api key!

1
2
3
4
5
6
7
8
9
import requests,json
def rest(address):

url = 'https://api.tomtom.com/search/2/geocode/{}.json?&key=YOUR_KEY&countrySet=TWN&language=zh-TW&limit=1'.format(
address)
response = requests.get(url)
data = response.text
js = json.loads(str(data))
return js['results'][0]['position']

ps. requests需要安裝,

1
conda install requests

然後使用這個rest函式,產生geometry(命名為geom)

1
2
# 這邊使用df.head()只取前五筆測試
geom=[Point(rest(row.address)) for idx, row in df.head().iterrows()]

有了geom就可以產生GeoDataFrame了,要注意的是,
這邊的坐標是WGS84,也就是epsg:4326

1
2
3
crs = {'init': 'epsg:4326'}
gdf = gpd.GeoDataFrame(df.head(), crs=crs, geometry=geom)
gdf

一樣,看看成果吧

GeoDataFrame可以輸出成GIS格式,用以在其他平台檢視與處理,包含常用的shp或是geojson

1
gdf.to_file(driver = 'ESRI Shapefile', filename = 'output/Light.shp')

今天的相關測試可以參考GitHub