如何根据shapefile屏蔽特定数组数据
how to mask the specific array data based on the shapefile
这是我的问题:
- 二维 numpy 数组数据表示每个网格的一些 属性 space
- 作为研究区域(如城市)的行政区划的 shapefile。
例如:
http://i4.tietuku.com/84ea2afa5841517a.png
整个区域都是40x40的网格,我想提取紫色区域内的数据。换句话说,我想屏蔽管理之外的数据
边界进入 np.nan。
我的早期尝试
我把格子号和select具体数组数据标注成np.nan。
http://i4.tietuku.com/523df4783bea00e2.png
value[0,:] = np.nan
value[1,:] = np.nan
.
.
.
.
谁能告诉我一个更简单的方法来实现目标?
添加
找到一个答案here,它可以将栅格数据绘制到 shapefile 中,但数据本身不会改变。
更新-2016-01-16
我已经在一些答案的启发下解决了这个问题。
对这个目标感兴趣的人,查看我问过的这两个帖子:
1.
2. How to use set clipped path for Basemap polygon
关键的一步是测试我已经转换成 shapely.polygon 的 shapefile 的点 within/out。
步骤 1. 栅格化 shapefile
创建一个函数,可以确定坐标 (x, y)
处的点是否在该区域中。有关如何将 shapefile 栅格化为与目标蒙版尺寸相同的数组的更多详细信息,请参阅 here
def point_is_in_mask(mask, point):
# this is just pseudocode
return mask.contains(point)
第 2 步。创建您的面具
mask = np.zeros((height, width))
value = np.zeros((height, width))
for y in range(height):
for x in range(width):
if not point_is_in_mask(mask, (x, y)):
value[y][x] = np.nan
最好使用 matplotlib
:
def outline_to_mask(line, x, y):
"""Create mask from outline contour
Parameters
----------
line: array-like (N, 2)
x, y: 1-D grid coordinates (input for meshgrid)
Returns
-------
mask : 2-D boolean array (True inside)
"""
import matplotlib.path as mplp
mpath = mplp.Path(line)
X, Y = np.meshgrid(x, y)
points = np.array((X.flatten(), Y.flatten())).T
mask = mpath.contains_points(points).reshape(X.shape)
return mask
或者,您可以使用上述答案中建议的 shapely
contains 方法。您可以通过递归细分 space 来加速计算,如本要点所示(但 matplotlib 解决方案在我的测试中快 1.5 倍):
https://gist.github.com/perrette/a78f99b76aed54b6babf3597e0b331f8
这是我的问题:
- 二维 numpy 数组数据表示每个网格的一些 属性 space
- 作为研究区域(如城市)的行政区划的 shapefile。
例如:
http://i4.tietuku.com/84ea2afa5841517a.png
整个区域都是40x40的网格,我想提取紫色区域内的数据。换句话说,我想屏蔽管理之外的数据 边界进入 np.nan。
我的早期尝试
我把格子号和select具体数组数据标注成np.nan。
http://i4.tietuku.com/523df4783bea00e2.png
value[0,:] = np.nan
value[1,:] = np.nan
.
.
.
.
谁能告诉我一个更简单的方法来实现目标?
添加
找到一个答案here,它可以将栅格数据绘制到 shapefile 中,但数据本身不会改变。
更新-2016-01-16
我已经在一些答案的启发下解决了这个问题。
对这个目标感兴趣的人,查看我问过的这两个帖子:
1.
2. How to use set clipped path for Basemap polygon
关键的一步是测试我已经转换成 shapely.polygon 的 shapefile 的点 within/out。
步骤 1. 栅格化 shapefile
创建一个函数,可以确定坐标 (x, y)
处的点是否在该区域中。有关如何将 shapefile 栅格化为与目标蒙版尺寸相同的数组的更多详细信息,请参阅 here
def point_is_in_mask(mask, point):
# this is just pseudocode
return mask.contains(point)
第 2 步。创建您的面具
mask = np.zeros((height, width))
value = np.zeros((height, width))
for y in range(height):
for x in range(width):
if not point_is_in_mask(mask, (x, y)):
value[y][x] = np.nan
最好使用 matplotlib
:
def outline_to_mask(line, x, y):
"""Create mask from outline contour
Parameters
----------
line: array-like (N, 2)
x, y: 1-D grid coordinates (input for meshgrid)
Returns
-------
mask : 2-D boolean array (True inside)
"""
import matplotlib.path as mplp
mpath = mplp.Path(line)
X, Y = np.meshgrid(x, y)
points = np.array((X.flatten(), Y.flatten())).T
mask = mpath.contains_points(points).reshape(X.shape)
return mask
或者,您可以使用上述答案中建议的 shapely
contains 方法。您可以通过递归细分 space 来加速计算,如本要点所示(但 matplotlib 解决方案在我的测试中快 1.5 倍):
https://gist.github.com/perrette/a78f99b76aed54b6babf3597e0b331f8