“ 叠加分析和数据聚合。”
01
—
叠加分析
叠加分析指将两个或多个数据图层按照空间位置关系进行叠加,以产生新的空间信息和属性信息的分析方法。作为示例,我们将根据两个面矢量,从数据中筛选出他们重叠的多边形单元。
示例数据依然可以从以下链接下载:
https://pan.baidu.com/s/1bAnUo0S_ojxXdkyBqWAnLg?pwd=gxu2 提取码: gxu2
首先,我们来读取数据。
import geopandas as gpdimport matplotlib.pyplot as plt# 根据文件本地存储位置调整路径border_fp = ".../borders.shp"grid_fp = ".../RailwayStation.shp"# Read filesgrid = gpd.read_file(grid_fp)hel = gpd.read_file(border_fp)
import geopandas as gpd
import matplotlib.pyplot as plt
# 根据文件本地存储位置调整路径
border_fp = ".../borders.shp"
grid_fp = ".../RailwayStation.shp"
# Read files
grid = gpd.read_file(grid_fp)
hel = gpd.read_file(border_fp)
我们检查他们的CRS是否相同。
hel.crs == grid.crsTrue
hel.crs == grid.crs
True
我们来绘制这两个矢量,看看是什么样子。
basemap = hel.plot(color='lightblue')grid.plot(ax=basemap, color='orange', linewidth=0.02, alpha=0.7);plt.tight_layout()plt.show()
basemap = hel.plot(color='lightblue')
grid.plot(ax=basemap, color='orange', linewidth=0.02, alpha=0.7);
plt.tight_layout()
plt.show()
我们使用overlay函数进行叠加分析,筛选出两个图层相交的多边形。
result = gpd.overlay(grid, hel, how='intersection')
我们绘制下结果。
result.plot(color="b")plt.tight_layout()plt.show()
result.plot(color="b")
现在结果中只包含了两个矢量图层相交的部分。
我们再来看看数据属性有哪些变化。
grid.columnsIndex(['car_m_d', 'car_m_t', 'car_r_d', 'car_r_t', 'from_id', 'pt_m_d', 'pt_m_t', 'pt_m_tt', 'pt_r_d', 'pt_r_t', 'pt_r_tt', 'to_id', 'walk_d', 'walk_t', 'geometry'], dtype='object')
grid.columns
Index(['car_m_d', 'car_m_t', 'car_r_d', 'car_r_t', 'from_id', 'pt_m_d',
'pt_m_t', 'pt_m_tt', 'pt_r_d', 'pt_r_t', 'pt_r_tt', 'to_id', 'walk_d',
'walk_t', 'geometry'],
dtype='object')
hel.columnsIndex(['GML_ID', 'NAMEFIN', 'NAMESWE', 'NATCODE', 'geometry'], dtype='object')
hel.columns
Index(['GML_ID', 'NAMEFIN', 'NAMESWE', 'NATCODE', 'geometry'], dtype='object')
result.columnsOut[6]: Index(['car_m_d', 'car_m_t', 'car_r_d', 'car_r_t', 'from_id', 'pt_m_d', 'pt_m_t', 'pt_m_tt', 'pt_r_d', 'pt_r_t', 'pt_r_tt', 'to_id', 'walk_d', 'walk_t', 'GML_ID', 'NAMEFIN', 'NAMESWE', 'NATCODE', 'geometry'], dtype='object')
result.columns
Out[6]:
'walk_t', 'GML_ID', 'NAMEFIN', 'NAMESWE', 'NATCODE', 'geometry'],
我们看到叠加后的矢量的属性字段是原矢量属性字段的并集。
我们将结果保存为GeoJSON文件,这是存储空间数据的另一种常用文件格式。
# 根据本地存储位置调整路径resultfp = ".../RailwayStation_Overlay.geojson"result.to_file(resultfp, driver="GeoJSON")
# 根据本地存储位置调整路径
resultfp = ".../RailwayStation_Overlay.geojson"
result.to_file(resultfp, driver="GeoJSON")
如果数据量较大,我们可以通过分批进行叠加分析以提升计算速度。
下面代码是一个完整的批处理示例。
import geopandas as gpdimport numpy as npimport pandas as pd# 根据文件本地存储位置调整路径border_fp = ".../borders.shp"grid_fp = ".../RailwayStation.shp" grid = gpd.read_file(grid_fp)hel = gpd.read_file(border_fp)# 处理批次b = 10# 批处理循环次数(取整)row_cnt = len(grid)iterations = int(np.ceil(row_cnt / b))final = gpd.GeoDataFrame()# 根据批处理次数设置开始和结束索引start_idx = 0end_idx = start_idx + bfor iteration in range(iterations): print("Iteration: %s/%s" % (iteration, iterations)) result = gpd.overlay(grid[start_idx:end_idx], hel, how='intersection') final = pd.concat([final, result], ignore_index=True) start_idx += b end_idx = start_idx + boutfp = ".../overlay.geojson"final.to_file(outfp, driver="GeoJSON")
import numpy as np
import pandas as pd
# 处理批次
b = 10
# 批处理循环次数(取整)
row_cnt = len(grid)
iterations = int(np.ceil(row_cnt / b))
final = gpd.GeoDataFrame()
# 根据批处理次数设置开始和结束索引
start_idx = 0
end_idx = start_idx + b
for iteration in range(iterations):
print("Iteration: %s/%s" % (iteration, iterations))
result = gpd.overlay(grid[start_idx:end_idx], hel, how='intersection')
final = pd.concat([final, result], ignore_index=True)
start_idx += b
outfp = ".../overlay.geojson"
final.to_file(outfp, driver="GeoJSON")
02
数据聚合
数据聚合本质上是指根据某个共同标识将多个几何对象合并在一起。举个例子,假设我们想要研究各大洲的某个数据,但手头只有相应的国家级别的数据(如国家数据集),通过聚合操作,就能将这些国家级数据转换为大洲级别的数据集。
下面,我们将根据重叠分析结果中的驾车出行时间对出行时间数据进行聚合,也就是说,与火车站驾车出行时间相同的数据将会被合并在一起。
result_aggregated = result.dissolve(by="car_r_t")result_aggregated.head() geometry car_m_d car_m_t \car_r_t -1 (POLYGON ((388000.0001354737 6669000.000042855... -1 -1 0 POLYGON ((386000.0001357812 6672000.000042388,... 0 0 7 POLYGON ((386250.0001357396 6671750.000042424,... 1059 7 8 (POLYGON ((386250.0001357467 6671500.000042468... 1207 8 9 (POLYGON ((387000.0001355996 6671500.000042449... 1768 8 car_r_d from_id pt_m_d pt_m_t pt_m_tt pt_r_d pt_r_t pt_r_tt \car_r_t -1 -1 5996387 -1 -1 -1 -1 -1 -1 0 0 5975375 0 0 0 0 0 0 7 1059 5977007 447 6 6 447 6 6 8 1207 5978638 1026 9 11 1026 9 11 9 1768 5980269 1274 11 15 1274 11 15 to_id walk_d walk_t GML_ID NAMEFIN NAMESWE NATCODE car_r_t -1 -1 -1 -1 27517366 Helsinki Helsingfors 091 0 5975375 0 0 27517366 Helsinki Helsingfors 091 7 5975375 447 6 27517366 Helsinki Helsingfors 091 8 5975375 774 11 27517366 Helsinki Helsingfors 091 9 5975375 1210 17 27517366 Helsinki Helsingfors 091
result_aggregated = result.dissolve(by="car_r_t")
result_aggregated.head()
geometry car_m_d car_m_t \
car_r_t
-1 (POLYGON ((388000.0001354737 6669000.000042855... -1 -1
0 POLYGON ((386000.0001357812 6672000.000042388,... 0 0
7 POLYGON ((386250.0001357396 6671750.000042424,... 1059 7
8 (POLYGON ((386250.0001357467 6671500.000042468... 1207 8
9 (POLYGON ((387000.0001355996 6671500.000042449... 1768 8
car_r_d from_id pt_m_d pt_m_t pt_m_tt pt_r_d pt_r_t pt_r_tt \
-1 -1 5996387 -1 -1 -1 -1 -1 -1
0 0 5975375 0 0 0 0 0 0
7 1059 5977007 447 6 6 447 6 6
8 1207 5978638 1026 9 11 1026 9 11
9 1768 5980269 1274 11 15 1274 11 15
to_id walk_d walk_t GML_ID NAMEFIN NAMESWE NATCODE
-1 -1 -1 -1 27517366 Helsinki Helsingfors 091
0 5975375 0 0 27517366 Helsinki Helsingfors 091
7 5975375 447 6 27517366 Helsinki Helsingfors 091
8 5975375 774 11 27517366 Helsinki Helsingfors 091
9 5975375 1210 17 27517366 Helsinki Helsingfors 091
因为数据聚合后,绘图效果看上去是一样的。所以我们对比一下聚合操作前后图层中的单元数量,就会发现我们数据中的行数确实减少了,这些多边形已合并在一起。
len(result)3836len(result_aggregated)51
len(result)
3836
len(result_aggregated)
51