空間分析:5-1.空間分析庫PySAL的使用
技術標籤:空間分析
Pysal與geoda非常相似,一個通過寫指令碼來實現空間分析,一個通過軟體操作來實現空間分析。
Pysal的官網對於自己的介紹是,開源、跨平臺的地理空間資料分析庫。
http://pysal.org/
Pysal能幹什麼?
空間分析+視覺化,就夠了。
一、pysal安裝
安裝非常簡單,把相關的包都裝一下。
pip install pysal
pip install esda
pip install geopandas
pip install splot
或者開啟Pycharm——File——Settings——Python Interpreter。
搜尋pysal和esda、geopandas、splot,點選install package安裝。
esda是進行連線分析的,geopandas是對geometry進行矩陣處理的,splot是繪圖的。
二、官網例子
Pysal官網,最上面就有三個例子:http://pysal.org/
照著這三個例子操作一遍,空間分析就算是入門了。
第一個柏林房價,就是算莫蘭指數的。
https://nbviewer.jupyter.org/github/pysal/esda/blob/master/notebooks/Spatial%20Autocorrelation%20for%20Areal%20Unit%20Data.ipynb
第二個是分析區域性空間自相關的集聚圖,LISA既是Local Indications of Spatial Association。
http://pysal.org/notebooks/explore/giddy/directional.html
第三個是計算空間權重的。
https://nbviewer.jupyter.org/github/pysal/splot/blob/master/notebooks/libpysal_non_planar_joins_viz.ipynb
三、測試資料
可以從git上獲取一些資料用來學習:https://github.com/ljwolf/geopython
四、demo指令碼
我用geopython-master\data裡的資料berlin-listings.csv和berlin-neighbourhoods.geojson做了個簡單的指令碼。
空間權重:
from libpysal.weights.contiguity import Queen
import libpysal
from libpysal import examples
import matplotlib.pyplot as plt
import geopandas as gpd
from splot.libpysal import plot_spatial_weights
gdf = gpd.read_file('data/berlin-neighbourhoods.geojson')
print(gdf.head())
weights = Queen.from_dataframe(gdf)
plot_spatial_weights(weights, gdf)
plt.show()
房價分佈情況:
import esda
import pandas as pd
import geopandas as gpd
from geopandas import GeoDataFrame
import libpysal as lps
import numpy as np
import matplotlib.pyplot as plt
from shapely.geometry import Point
# %matplotlib inline
gdf = gpd.read_file('data/berlin-neighbourhoods.geojson')
bl_df = pd.read_csv('data/berlin-listings.csv')
geometry = [Point(xy) for xy in zip(bl_df.longitude, bl_df.latitude)]
crs = {'init': 'epsg:4326'}
bl_gdf = GeoDataFrame(bl_df, crs=crs, geometry=geometry)
bl_gdf['price'] = bl_gdf['price'].astype('float32')
sj_gdf = gpd.sjoin(gdf, bl_gdf, how='inner', op='intersects', lsuffix='left', rsuffix='right')
median_price_gb = sj_gdf['price'].groupby([sj_gdf['neighbourhood_group']]).mean()
print(median_price_gb)
gdf = gdf.join(median_price_gb, on='neighbourhood_group')
gdf.rename(columns={'price': 'median_pri'}, inplace=True)
print(gdf.head(15))
pd.isnull(gdf['median_pri']).sum()
gdf['median_pri'].fillna((gdf['median_pri'].mean()), inplace=True)
gdf.plot(column='median_pri')
plt.show()
LISA集聚圖:
import libpysal
import numpy as np
from giddy.directional import Rose
import matplotlib.pyplot as plt
f = open(libpysal.examples.get_path('spi_download.csv'), 'r')
lines = f.readlines()
f.close()
lines = [line.strip().split(",") for line in lines]
names = [line[2] for line in lines[1:-5]]
data = np.array([list(map(int, line[3:])) for line in lines[1:-5]])
sids = list(range(60))
out = ['"United States 3/"',
'"Alaska 3/"',
'"District of Columbia"',
'"Hawaii 3/"',
'"New England"','"Mideast"',
'"Great Lakes"',
'"Plains"',
'"Southeast"',
'"Southwest"',
'"Rocky Mountain"',
'"Far West 3/"']
snames = [name for name in names if name not in out]
sids = [names.index(name) for name in snames]
states = data[sids,:]
us = data[0]
years = np.arange(1969, 2009)
rel = states/(us*1.)
gal = libpysal.io.open(libpysal.examples.get_path('states48.gal'))
w = gal.read()
w.transform = 'r'
Y = rel[:, [0, -1]]
# Y.shape
# Y
np.random.seed(100)
r4 = Rose(Y, w, k=4)
r4.plot()
plt.show()
五、總結
空間分析,Geoda和pysal,用哪個都行,只要能實現目的,無所謂用軟體,還是編寫程式。