python函数五要素_GeoPandas入门 | 01-地理数据介绍

01-地理数据介绍

源代码请看此处

1.1 Python地理空间矢量数据简介

%matplotlib inline

import pandas as pd

import geopandas

导入地理数据

地理空间数据通常可以从特定的GIS文件格式或数据存储中获得,如ESRI shapefiles、GeoJSON文件、geopackage文件、PostGIS(PostgreSQL)数据库、...

我们可以使用GeoPandas库中的geopandas.read_file函数,来读取其中的很多GIS文件格式(依靠的是fiona库,它是GDAL/OGR的python接口)。

例如,我们先读取一个包含世界所有国家边界的shapefile文件,zip文件放到在/data目录下)。

countries=geopandas.read_file("zip://data/ne_110m_admin_0_countries.zip")

countries.head()

featurecla scalerank LABELRANK SOVEREIGNT SOV_A3 ADM0_DIF LEVEL TYPE ADMIN ADM0_A3 ... NAME_KO NAME_NL NAME_PL NAME_PT NAME_RU NAME_SV NAME_TR NAME_VI NAME_ZH geometry
0 Admin-0 country 1 6 Fiji FJI 0 2 Sovereign country Fiji FJI ... 피지 Fiji Fidżi Fiji Фиджи Fiji Fiji Fiji 斐濟 MULTIPOLYGON (((180.00000 -16.06713, 180.00000...
1 Admin-0 country 1 3 United Republic of Tanzania TZA 0 2 Sovereign country United Republic of Tanzania TZA ... 탄자니아 Tanzania Tanzania Tanzânia Танзания Tanzania Tanzanya Tanzania 坦桑尼亚 POLYGON ((33.90371 -0.95000, 34.07262 -1.05982...
2 Admin-0 country 1 7 Western Sahara SAH 0 2 Indeterminate Western Sahara SAH ... 서사하라 Westelijke Sahara Sahara Zachodnia Saara Ocidental Западная Сахара Västsahara Batı Sahra Tây Sahara 西撒哈拉 POLYGON ((-8.66559 27.65643, -8.66512 27.58948...
3 Admin-0 country 1 2 Canada CAN 0 2 Sovereign country Canada CAN ... 캐나다 Canada Kanada Canadá Канада Kanada Kanada Canada 加拿大 MULTIPOLYGON (((-122.84000 49.00000, -122.9742...
4 Admin-0 country 1 2 United States of America US1 1 2 Country United States of America USA ... 미국 Verenigde Staten van Amerika Stany Zjednoczone Estados Unidos Соединённые Штаты Америки USA Amerika Birleşik Devletleri Hoa Kỳ 美国 MULTIPOLYGON (((-122.84000 49.00000, -120.0000...

5 rows × 95 columns

countries.plot()

我们可以观察到:

使用 .head()可以得到数据集的前五列,就像使用Pandas一样

有一个 geometry列,用于存储不同的国家的边界多边形

我们可以使用 .plot()方法来快速得到数据的基本可视化效果

1.2 GeoDataFrame 介绍

我们使用GeoPandas库来读取地理空间数据,然后返回一个GeoDataFrame对象。

type(countries)

geopandas.geodataframe.GeoDataFrame

一个GeoDataFrame包含一个表格式的地理空间数据集

它有一个geometry列,用来保存几何信息(或GeoJSON要素)

其他列是描述每个几何体的属性(或GeoJSON属性)

这样的GeoDataFrame就像pandas.DataFrame一样,但它具有一些额外的功能,用于处理地理空间数据

一个.geometry属性,总是返回带有几何信息的列(返回一个GeoSeries)。列名本身不一定是 geometry,但它总是作为.geometry属性被访问。

它有一些额外的方法来处理空间数据(面积、距离、缓冲区、交叉点......),我们将在后面的教程中看到

countries.geometry

0 MULTIPOLYGON (((180.00000 -16.06713, 180.00000...

1 POLYGON ((33.90371 -0.95000, 34.07262 -1.05982...

2 POLYGON ((-8.66559 27.65643, -8.66512 27.58948...

3 MULTIPOLYGON (((-122.84000 49.00000, -122.9742...

4 MULTIPOLYGON (((-122.84000 49.00000, -120.0000...

...

172 POLYGON ((18.82982 45.90887, 18.82984 45.90888...

173 POLYGON ((20.07070 42.58863, 19.80161 42.50009...

174 POLYGON ((20.59025 41.85541, 20.52295 42.21787...

175 POLYGON ((-61.68000 10.76000, -61.10500 10.890...

176 POLYGON ((30.83385 3.50917, 29.95350 4.17370, ...

Name: geometry, Length: 177, dtype: geometry

type(countries.geometry)

geopandas.geoseries.GeoSeries

countries.geometry.area

0 1.639511

1 76.301964

2 8.603984

3 1712.995228

4 1122.281921

...

172 8.604719

173 1.479321

174 1.231641

175 0.639000

176 51.196106

Length: 177, dtype: float64

它仍然是一个DataFrame,所以我们可以在地理空间数据集上使用所有的pandas功能,并对属性和几何信息一起进行数据操作

例如,我们可以计算所有国家的平均人口数量(通过访问'POP_EST'列,并调用平均值方法)。

countries['POP_EST'].mean() # 计算所有国家的平均人口数量

41712369.84180791

或者,我们可以使用布尔筛选器,根据条件选择数据框的一个子集

africa=countries[countries['CONTINENT']=='Africa']

africa.plot()

本教程的其余部分将假设你已经知道一些Pandas的基础知识,但我们会尽量为那些不熟悉的人提供这部分的提示

如果你想了解更多关于pandas的知识,可以参考一些资源

知识点:

GeoDataFrame 可以将典型的表格数据分析与空间操作结合起来进行

GeoDataFrame(或要素集,Feature Collection)由以下部分组成:

Geometries或features:空间对象

Attributes或properties:包含每个空间对象的非空间信息的列

1.3 矢量要素:点、线、面

空间矢量数据可以包括不同的类型,3种基本类型是:

点数据:表示空间中的一个点

线条数据(LineString):表示构成一条线的点的序列

多边形数据:表示一个填充区域

它们中的每一个都可以组合成多部分的矢量数据(参见https://shapely.readthedocs.io/en/stable/manual.html#geometric-objects 查看详细的概述)。在我们目前看到的例子中,各个矢量对象都是多边形

print(countries.geometry[2])

POLYGON ((-8.665589565454809 27.65642588959236, -8.665124477564191 27.58947907155823, -8.684399786809053 27.39574412689601, -8.6872936670174 25.88105621998891, -11.96941891117116 25.93335276946827, -11.93722449385332 23.37459422453617, -12.87422156416958 23.28483226164518, -13.11875444177471 22.77122020109626, -12.92910193526353 21.32707062426756, -16.84519365077399 21.33332347257488, -17.06342322434257 20.99975210213083, -17.02042843267577 21.42231028898158, -17.00296179856109 21.42073415779658, -14.75095455571353 21.50060008390366, -14.63083268885107 21.8609398462749, -14.22116777185725 22.31016307218816, -13.89111039880905 23.6910090194593, -12.50096269372537 24.7701162785782, -12.03075883630163 26.03086619720307, -11.71821977380036 26.10409170176062, -11.39255489749701 26.88342397715439, -10.55126257978527 26.99080760345689, -10.18942420087758 26.86094472910741, -9.735343390328879 26.86094472910741, -9.41303748212448 27.08847606048857, -8.794883999049077 27.12069631602251, -8.817828334986672 27.65642588959236, -8.665589565454809 27.65642588959236))

让我们导入一些其他具有不同类型几何对象的数据集:

一个世界各城市数据集,由Point数据组成

cities = geopandas.read_file("zip://data/ne_110m_populated_places.zip")

print(cities.geometry[0])

POINT (12.45338654497177 41.90328217996012)

还有一个世界河流的数据集,zip文件在/data目录下,每条河流都是一条LineString

# ! wget https://naciscdn.org/naturalearth/50m/physical/ne_50m_rivers_lake_centerlines.zip

--2020-08-12 00:23:33-- https://naciscdn.org/naturalearth/50m/physical/ne_50m_rivers_lake_centerlines.zip

Resolving naciscdn.org (naciscdn.org)... 146.201.97.163

Connecting to naciscdn.org (naciscdn.org)|146.201.97.163|:443... connected.

HTTP request sent, awaiting response... 200 OK

Length: 457951 (447K) [application/zip]

Saving to: ‘ne_50m_rivers_lake_centerlines.zip’

ne_50m_rivers_lake_ 100%[===================>] 447.22K 8.16KB/s in 53s

2020-08-12 00:24:31 (8.43 KB/s) - ‘ne_50m_rivers_lake_centerlines.zip’ saved [457951/457951]

rivers = geopandas.read_file("zip://data/ne_50m_rivers_lake_centerlines.zip")

print(rivers.geometry[0])

LINESTRING (51.9371337598152 55.70106609892139, 51.88086646731369 55.68625891701544, 51.82031249962222 55.69745514553858, 51.7476018274624 55.69366250841807, 51.6628417966117 55.60817291874525, 51.57871093775964 55.59943268477065, 51.51342773400279 55.58312409100404, 51.50854492161091 55.52948639548083, 51.48583984403365 55.49640534033426, 51.36914062543957 55.46796295772435, 51.21306254869774 55.50264985760492, 51.13452148447897 55.48273346527725, 51.07934570274205 55.46759674659262, 50.98022460947817 55.46637604371949, 50.83445217522774 55.45630956063775, 50.6883789060617 55.42011139502489, 50.4118652342932 55.40119049644431, 50.07802734358711 55.38112213757665, 49.82216796867687 55.33466217681809, 49.53222656260584 55.260614325191, 49.38232421848795 55.17182037990665, 49.24808475131027 55.11301870345045)

1.4 shapely库简介

各个Geometry对象由shapely库提供支持

type(countries.geometry[0])

shapely.geometry.multipolygon.MultiPolygon

下面是使用shapely构建矢量要素的方法

from shapely.geometry import Point, Polygon, LineString

p=Point(0,0)

print(p)

POINT (0 0)

polygon=Polygon([(1,1),(2,2),(2,1)])

polygon.area

0.5

polygon.distance(p) # 多边形到点的最近距离

1.4142135623730951

知识点:

GeoPandas中的矢量对象是由shapely库继承得到的

如果访问一个GeoDataFrame的geometry对象,则得到一个shapely几何体对象

这些对象具有类似于geopandas对象(GeoDataFrame/GeoSeries)的功能

1.5 图层叠加显示

ax=countries.plot(edgecolor='k',facecolor='none',figsize=(15,10))

rivers.plot(ax=ax)

cities.plot(ax=ax,color='red')

ax.set(xlim=(73,135),ylim=(0,55))

[(0.0, 55.0), (73.0, 135.0)]

参见04-更多关于可视化,了解更多关于地理空间数据集可视化的细节

1.6 本章练习

在本课程的练习中,我们将使用几个关于巴黎市的数据集:

巴黎的行政区划: paris_districts_utm.geojson

巴黎公共自行车站点数据:paris_bike_stations_mercator.gpkg。

1.6.1 练习一

探索自行车站点数据data/paris_bike_stations_mercator.gpkg

读取stations数据集

检查读取返回对象的类型type()

检查数据框的第一行,探索这个数据集包含什么样的矢量要素及其字段

检查数据集中的要素的数量

stations=geopandas.read_file('data/paris_bike_stations_mercator.gpkg')

type(stations)

geopandas.geodataframe.GeoDataFrame

stations.head()

name bike_stands available_bikes geometry
0 14002 - RASPAIL QUINET 44 4 POINT (259324.887 6247620.771)
1 20503 - COURS DE VINCENNES PYRÉNÉES 21 3 POINT (267824.377 6249062.894)
2 20011 - PYRÉNÉES-DAGORNO 21 0 POINT (267742.135 6250378.469)
3 31008 - VINCENNES (MONTREUIL) 56 0 POINT (271326.638 6250750.824)
4 43006 - MINIMES (VINCENNES) 28 27 POINT (270594.689 6248007.705)

stations.shape

(1226, 4)

1.6.2 练习二

station的快速可视化实现

使用figsize参数调整可视化图片大小

stations.plot()

stations.plot(figsize=(12,6))

一个只显示点的图,如果没有任何空间背景,是很难解释的。因此,在接下来的练习中,我们将学习如何添加背景图。

我们要利用contextily包,这个包的add_basemap()函数可以很容易地给我们的绘图添加一个网络地图背景。我们首先绘制数据,然后将matplotlib axes对象(由dataframe的plot()方法返回)传递给add_basemap()函数,然后contextily将下载你的绘图地理范围所需的地图瓦片

# ! pip3 install contextily

import contextily

axes=stations.plot(figsize=(12,6), markersize=5)

contextily.add_basemap(axes)

1.6.3 练习三

做一个统计直方图,显示的自行车站数量分布情况

stations['bike_stands'].hist()

1.6.4 练习四

绘制stations数据集的分布图(figsize=(12,6))

使用available_bikes列确定点的颜色(使用column=参数)

使用 legend=True 参数显示色带(color bar)

stations.plot(column='available_bikes',legend=True,figsize=(12,6))

1.6.5 练习五

探索巴黎行政区的数据集(作为GeoJSON文件提供:"data/paris_districts_utm.geojson")

将数据集读入名为的GeoDataFramedistricts

检查GeoDataFrame的第一行,该数据集包含哪些属性字段?

检查数据集中有多少个要素

districts快速可视化,figsize=(12,6)

districts=geopandas.read_file("data/paris_districts_utm.geojson")

districts.head()

id district_name population geometry
0 1 St-Germain-l'Auxerrois 1672 POLYGON ((451922.133 5411438.484, 451922.080 5...
1 2 Halles 8984 POLYGON ((452278.419 5412160.893, 452192.407 5...
2 3 Palais-Royal 3195 POLYGON ((451553.806 5412340.522, 451528.058 5...
3 4 Place-Vendôme 3044 POLYGON ((451004.908 5412654.095, 450960.640 5...
4 5 Gaillon 1345 POLYGON ((451328.752 5412991.278, 451294.721 5...

districts.shape

(80, 4)

districts.plot(figsize=(12,6))

1.6.6 练习六 找出面积最大的区

计算每个区的面积

将面积列作为新属性添加到districts dataframe中

按从大到小的区域列对dataframe进行排序(降序)

districts.geometry.area

0 8.685379e+05

1 4.122371e+05

2 2.735494e+05

3 2.693111e+05

4 1.879097e+05

...

75 1.294254e+06

76 8.061191e+05

77 1.486139e+06

78 1.598127e+06

79 2.089783e+06

Length: 80, dtype: float64

# 转换为km² 10^6

districts['area'] = districts.geometry.area / 1e6

districts.sort_values(by='area', ascending=False)

id district_name population geometry area
45 46 Picpus 62947 POLYGON ((456790.759 5408686.978, 456841.941 5... 7.201383
60 61 Auteuil 67967 POLYGON ((444930.499 5411923.067, 444957.444 5... 6.380679
44 45 Bel-Air 33976 POLYGON ((456987.121 5409120.599, 456996.502 5... 5.967841
61 62 Muette 45214 POLYGON ((444686.860 5413985.234, 445358.893 5... 5.475037
62 63 Porte-Dauphine 27423 POLYGON ((446548.869 5414236.010, 447025.036 5... 3.085061
... ... ... ... ... ...
9 10 Enfants-Rouges 8562 POLYGON ((453580.220 5412266.849, 453591.609 5... 0.271603
3 4 Place-Vendôme 3044 POLYGON ((451004.908 5412654.095, 450960.640 5... 0.269311
5 6 Vivienne 2917 POLYGON ((451686.936 5412747.032, 451682.879 5... 0.243418
11 12 Sainte-Avoie 7501 POLYGON ((452928.277 5412227.550, 452830.786 5... 0.213201
4 5 Gaillon 1345 POLYGON ((451328.752 5412991.278, 451294.721 5... 0.187910

80 rows × 5 columns

EXERCISE:

增加一列population_density 代表人口密度,即每平方公里的居民数量(注意:面积函数计算得到的面积以平方米为单位,所以需要将结果乘以10**6)

根据population_density字段对多边形进行上色,使用column=参数

使用 legend=True 参数显示色带(color bar)

districts['population_density'] = districts['population'] / districts.geometry.area * 10**6

districts.plot(column='population_density', figsize=(12, 6), legend=True)

districts.plot(column='population', figsize=(12, 6), legend=True)

1.7 关于导入和创建GeoDataFrames的更多信息

GeoPandas使用Fiona库(与GDAL/OGR的python接口)来读写数据。GeoPandas提供了一个更加用户友好的函数接口,这对于大多数用例来说已经足够了。但有时你需要更多的控制,在这种情况下,要用Fiona读取文件,你可以执行以下操作:

import fiona

from shapely.geometry import shape

with fiona.Env():

with fiona.open("zip://data/ne_110m_admin_0_countries.zip") as collection:

for feature in collection:

geom=shape(feature['geometry'])

print(feature['properties']['NAME'])

Fiji

Tanzania

W. Sahara

Canada

United States of America

Kazakhstan

Uzbekistan

Papua New Guinea

Indonesia

Argentina

Chile

Dem. Rep. Congo

Somalia

Kenya

Sudan

Chad

Haiti

Dominican Rep.

Russia

Bahamas

Falkland Is.

Norway

Greenland

Fr. S. Antarctic Lands

Timor-Leste

South Africa

Lesotho

Mexico

Uruguay

Brazil

Bolivia

Peru

Colombia

Panama

Costa Rica

Nicaragua

Honduras

El Salvador

Guatemala

Belize

Venezuela

Guyana

Suriname

France

Ecuador

Puerto Rico

Jamaica

Cuba

Zimbabwe

Botswana

Namibia

Senegal

Mali

Mauritania

Benin

Niger

Nigeria

Cameroon

Togo

Ghana

Côte d'Ivoire

Guinea

Guinea-Bissau

Liberia

Sierra Leone

Burkina Faso

Central African Rep.

Congo

Gabon

Eq. Guinea

Zambia

Malawi

Mozambique

eSwatini

Angola

Burundi

Israel

Lebanon

Madagascar

Palestine

Gambia

Tunisia

Algeria

Jordan

United Arab Emirates

Qatar

Kuwait

Iraq

Oman

Vanuatu

Cambodia

Thailand

Laos

Myanmar

Vietnam

North Korea

South Korea

Mongolia

India

Bangladesh

Bhutan

Nepal

Pakistan

Afghanistan

Tajikistan

Kyrgyzstan

Turkmenistan

Iran

Syria

Armenia

Sweden

Belarus

Ukraine

Poland

Austria

Hungary

Moldova

Romania

Lithuania

Latvia

Estonia

Germany

Bulgaria

Greece

Turkey

Albania

Croatia

Switzerland

Luxembourg

Belgium

Netherlands

Portugal

Spain

Ireland

New Caledonia

Solomon Is.

New Zealand

Australia

Sri Lanka

China

Taiwan

Italy

Denmark

United Kingdom

Iceland

Azerbaijan

Georgia

Philippines

Malaysia

Brunei

Slovenia

Finland

Slovakia

Czechia

Eritrea

Japan

Paraguay

Yemen

Saudi Arabia

Antarctica

N. Cyprus

Cyprus

Morocco

Egypt

Libya

Ethiopia

Djibouti

Somaliland

Uganda

Rwanda

Bosnia and Herz.

Macedonia

Serbia

Montenegro

Kosovo

Trinidad and Tobago

S. Sudan

1.7.1 手动构建一个GeoDataFrame

geopandas.GeoDataFrame({

'geometry':[Point(1,1),Point(2,2)],

'attribute1':[1,2],

'attribute2':[0.1,0.2]

})

geometry attribute1 attribute2
0 POINT (1.00000 1.00000) 1 0.1
1 POINT (2.00000 2.00000) 2 0.2

1.7.2 根据已有的dataframe创建一个GeoDataFrame

df = pd.DataFrame(

{'City': ['Buenos Aires', 'Brasilia', 'Santiago', 'Bogota', 'Caracas'],

'Country': ['Argentina', 'Brazil', 'Chile', 'Colombia', 'Venezuela'],

'Latitude': [-34.58, -15.78, -33.45, 4.60, 10.48],

'Longitude': [-58.66, -47.91, -70.66, -74.08, -66.86]})

df

City Country Latitude Longitude
0 Buenos Aires Argentina -34.58 -58.66
1 Brasilia Brazil -15.78 -47.91
2 Santiago Chile -33.45 -70.66
3 Bogota Colombia 4.60 -74.08
4 Caracas Venezuela 10.48 -66.86

gdf=geopandas.GeoDataFrame(df,geometry=geopandas.points_from_xy(df.Longitude,df.Latitude))

gdf

City Country Latitude Longitude geometry
0 Buenos Aires Argentina -34.58 -58.66 POINT (-58.66000 -34.58000)
1 Brasilia Brazil -15.78 -47.91 POINT (-47.91000 -15.78000)
2 Santiago Chile -33.45 -70.66 POINT (-70.66000 -33.45000)
3 Bogota Colombia 4.60 -74.08 POINT (-74.08000 4.60000)
4 Caracas Venezuela 10.48 -66.86 POINT (-66.86000 10.48000)

浏览http://geopandas.readthedocs.io/en/latest/gallery/create_geopandas_from_pandas.html 查看更多例子

你可能感兴趣的:(python函数五要素)