(數據科學學習手札77)基於geopandas的空間數據分析——文件IO

本文對應代碼和數據已上傳至個人Github倉庫https://github.com/CNFeffery/DataScienceStudyNoteshtml

1 簡介

  在上一篇文章中咱們對geopandas中的座標參考系有了較爲深刻的學習,而在平常空間數據分析工做中矢量文件的讀入和寫出,是相當重要的環節。python

  做爲基於geopandas的空間數據分析系列文章的第三篇,經過本文你將會學習到geopandas中的文件IOgit

2 文件IO

2.1 矢量文件的讀入

  geopandasfiona做爲操縱矢量數據讀寫功能的後端,使用geopandas.read_file()讀取對應類型文件,而在後端其實是使用fiona.open來讀入數據,即二者參數是保持一致的,讀入的數據自動轉換爲GeoDataFrame,下面是geopandas.read_file()主要參數:github

filename:str類型,傳入文件對應的路徑或url layer:str類型,當要讀入的數據格式爲地理數據庫.gdbQGIS中的.gpkg時,傳入對應圖層的名稱web

  下面結合上述參數,來介紹一下使用geopandas.read_file()在不一樣狀況下讀取常見格式矢量數據的方法,使用到的示例數據爲中國地圖,CRSEPSG:4326,本文使用到的全部數據均可以在文章開頭說起的Github倉庫對應本文路徑下找到:數據庫

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225132841878-1892879651.png" style="zoom:75%;"></img></center><center><font size=2>圖1</font></center>json

2.1.1 shapefile

  做爲很是常見的一種矢量文件格式,geopandasshapefile提供了很好的讀取和寫出支持,下面分爲不一樣狀況來介紹:後端

  • 完整的shapefile

  如圖2,這是一個完整的shapefilebash

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225132850233-1458701775.png" style="zoom:100%;"></img></center><center><font size=2>圖2</font></center>框架

  使用geopandas來讀取這種形式的shapefile很簡單:

import geopandas as gpd

data = gpd.read_file('geometry/china_provinces/china_provinces.shp')
print(data.crs) # 查看數據對應的crs
data.head() # 查看前5行

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225132859933-246445972.png" style="zoom:80%;"></img></center><center><font size=2>圖3</font></center>

  • 缺乏投影的shapefile

  當shapefile中缺失.prj文件時,使用geopandas讀入後造成的GeoDataFrame會缺失crs屬性:   

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225132909814-786739378.png" style="zoom:80%;"></img></center><center><font size=2>圖4</font></center>

  若是已經知道數據對應的CRS,能夠在讀入數據後補充上crs信息以進行其餘操做:

import pyproj

data.crs = pyproj.CRS.from_user_input('EPSG:4326')
data.crs

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225132918753-807764122.png" style="zoom:80%;"></img></center><center><font size=2>圖5</font></center>

  • 直接讀取文件夾

  當文件夾下只有單個shapefile時,能夠直接讀取該文件夾:

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225132934773-490544145.png" style="zoom:80%;"></img></center><center><font size=2>圖6</font></center>

  • 讀取zip壓縮包中的文件

  geopandas經過傳入特定語法格式的文件路徑信息,以支持直接讀取.zip格式壓縮包中的shapefile文件,主要分爲兩種狀況。   當文件在壓縮包內的根目錄時,使用下面的語法規則來讀取數據:

zip://路徑/xxx.zip

  譬如咱們要讀取圖7所示的壓縮包內文件:

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225132945818-1711366862.png" style="zoom:75%;"></img></center><center><font size=2>圖7</font></center>

  按照對應的語法規則,讀取該類型數據方式以下:

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225132956893-2043405839.png" style="zoom:80%;"></img></center><center><font size=2>圖8</font></center>

  而當文件在壓縮包內的文件夾中時,如圖9:   

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133009647-471588474.png" style="zoom:80%;"></img></center><center><font size=2>圖9</font></center>

  使用下面的語法規則來讀取數據:

zip://路徑/xxx.zip!壓縮包內指定文件路徑

  將上述語法運用到上述文件:

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133019138-658110373.png" style="zoom:80%;"></img></center><center><font size=2>圖10</font></center>

2.1.2 gdb與gpkg

  對於Arcgis中的地理數據庫gdb,以及QGIS中的GeoPackage,要讀取其包含的矢量數據,就要涉及到圖層的概念,對應geopandas.read_file()layer參數,只須要將gdbgpkg文件路徑做爲filename參數,再將對應的圖層名稱做爲layer參數傳入:

  • gdb
data = gpd.read_file('geometry/china_provinces.gdb', 
                     layer='china_provinces')
print(data.crs) # 查看數據對應的crs
data.head() # 查看前5行

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133031253-163405040.png" style="zoom:80%;"></img></center><center><font size=2>圖11</font></center> - **gpkg**

  相似讀入gdb文件:

data = gpd.read_file('geometry/china_provinces.gpkg', 
                     layer='china_provinces',
                     encoding='utf-8')
print(data.crs) # 查看數據對應的crs
data.head() # 查看前5行

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133039558-1881763371.png" style="zoom:80%;"></img></center><center><font size=2>圖12</font></center>

2.1.3 GeoJSON

  做爲web地圖中最常使用的矢量數據格式,GeoJSON幾乎被全部在線地圖框架做爲數據源格式,在geopandas中讀取GeoJSON很是簡單,只須要傳入文件路徑名稱便可,下面咱們來讀入圖13所示的文件:

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133049563-1354089913.png" style="zoom:80%;"></img></center><center><font size=2>圖13</font></center>

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133057942-686792753.png" style="zoom:80%;"></img></center><center><font size=2>圖14</font></center>

2.1.4 過濾

  geopandas在0.1.0版本中新增了bbox過濾,在0.7.0版本中新增了蒙版過濾行過濾功能,能夠輔助咱們根據本身的須要讀入原始數據中的子集,下面一一進行介紹:

  • bbox過濾

  bbox過濾容許咱們在read_file()中傳入一個邊界框做爲參數bbox,格式爲(左下角x, 左下角y, 右上角x, 右上角y),這樣在讀入的過程當中只會保留幾何對象與bbox有相交的數據記錄,下面咱們仍然以上文中使用過的中國地圖數據爲例,咱們在讀入的過程當中,傳入邊界框:

from shapely import geometry

data = gpd.read_file('geometry/china_provinces.json',
                    bbox=(100, 20, 110, 30))

%matplotlib widget
ax = data.plot()
# 繪製bbox框示意
ax = gpd.GeoSeries([geometry.box(minx=100, 
                                 miny=20, 
                                 maxx=110, 
                                 maxy=30).boundary]).plot(ax=ax, color='red')

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133105453-1581916323.png" style="zoom:80%;"></img></center><center><font size=2>圖15</font></center>

  能夠看到只有跟紅色框有相交的幾何對象被讀入。

  • 蒙版過濾

  蒙版過濾bbox過濾功能類似,都是篩選與指定區域相交的數據記錄,不一樣的是蒙版過濾經過mask參數能夠傳入任意形狀的多邊形,再也不像bbox過濾那樣只接受矩形:

data = gpd.read_file('geometry/china_provinces.json',
                    mask=geometry.Polygon([(100, 20), (110, 30), (120, 20)]))

ax = data.plot()
# 繪製bbox框示意
ax = gpd.GeoSeries([geometry.Polygon([(100, 20), 
                                      (110, 30), 
                                      (120, 20)]).boundary]).plot(ax=ax, color='red')

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133113158-1198225670.png" style="zoom:80%;"></img></center><center><font size=2>圖16</font></center>

  能夠看到只有跟紅色多邊形相交的幾何對象被讀入。

  • 行過濾

  行過濾的功能就比較簡單,經過參數rows控制讀入原數據的前若干行,能夠用於在讀取大型數據時先快速查看前幾行以瞭解整個數據的格式:

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133120283-1743802169.png" style="zoom:80%;"></img></center><center><font size=2>圖17</font></center>

2.2 矢量文件的寫出

  在geopandas中使用to_file()來將GeoDataFrameGeoSeries寫出爲矢量文件,主要支持shapefileGeoJSON以及GeoPackage,不像geopandas.read_file()能夠根據傳入的文件名稱信息自動推斷類型,咱們在寫出矢量數據時就須要使用driver參數來聲明文件類型:

  • ESRI Shapefile

  咱們將上文最後一次讀入的GeoDataFrame寫出爲ESRI Shapefile,設置driver參數爲ESRI Shapefile,若是你對文件編碼有要求,這裏可使用encoding參數來指定,譬如這裏咱們指定爲utf-8

'''在工程根目錄下建立output文件夾'''
import os

try:
    os.mkdir('output')
except FileExistsError:
    pass
    
data.to_file('output/output.shp', 
             driver='ESRI Shapefile',
             encoding='utf-8')

  能夠看到在output文件夾下,成功導出了完整的shapefile

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133129223-38916263.png" style="zoom:80%;"></img></center><center><font size=2>圖18</font></center>

  而若是導出的文件名不加後綴擴展名,則會生成包含在新目錄下的shapefile

data.to_file('output/output_shapefile', 
             driver='ESRI Shapefile',
             encoding='utf-8')

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133137048-1202954666.png" style="zoom:80%;"></img></center><center><font size=2>圖19</font></center>

  也能夠向指定的文件夾下追加圖層:

data.to_file('output/output_shapefile_multi_layer', 
             driver='ESRI Shapefile',
             layer='layer1',
             encoding='utf-8')

data.to_file('output/output_shapefile_multi_layer', 
             driver='ESRI Shapefile',
             layer='layer2',
             encoding='utf-8')

data.to_file('output/output_shapefile_multi_layer', 
             driver='ESRI Shapefile',
             layer='layer3',
             encoding='utf-8')

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133145283-925661579.png" style="zoom:80%;"></img></center><center><font size=2>圖20</font></center>

  • GeoPackage

  對於gdb文件,因爲ESRI的限制,暫時沒法在開源的geopandas中導出,但咱們能夠用QGIS中的GeoPackage做爲替代方案(開源世界萬歲O(∩_∩)O~~),只須要將driver參數設置爲GPKG便可,這裏須要注意一個bug:在使用geopandas導出GeoPackage文件時,可能會出現圖21所示錯誤:

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133154163-554486077.png" style="zoom:80%;"></img></center><center><font size=2>圖21</font></center>

  但我觀察到即便出現了上述錯誤,GeoPackage文件也是成功保存到路徑下的且整個程序並未被打斷,所以能夠無視上述錯誤:

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133202343-273258812.png" style="zoom:80%;"></img></center><center><font size=2>圖22</font></center>

  • GeoJSON

  寫出爲GeoJSON很是容易,只須要設置driver='GeoJSON'便可:

<center><img src="https://img2018.cnblogs.com/blog/1344061/202002/1344061-20200225133213773-1457528027.png" style="zoom:80%;"></img></center><center><font size=2>圖23</font></center>

  以上就是本文的所有內容,若有筆誤望指出!

原文出處:https://www.cnblogs.com/feffery/p/12301966.html

相關文章
相關標籤/搜索