使用Python实现子区域数据分类统计

前言

将近两年前,我写过一篇同名文章(见使用Python实现子区域数据分类统计)。

当时是为了统计县域内的植被覆盖量,折腾了一段时间,解决了这个问题。最近,又碰到了一个类似的需求,也需要统计某个小范围内的数据。简单来说,这个需求是将两个 shp 文件的任意两个对象做相交判断,最后形成一个新的空间对象集合,最后对此集合进行简单统计分析即可。

解决方案

明白了这一点之后,再看之前的代码,就发现当时用了很笨的方法。写了两个循环,先是取出大范围的 shp 中的每一个对象,再读取小范围 shp 的每一个对象,将小范围的 shp 空间对象逐个与大的空间对象进行相交操作。循环操作,就能将大范围的 shp 对象完全切割完毕。这段话说的稍微有些绕,感兴趣的可以直接看一下上篇文章。

今天又一次碰到了这个问题,回头找到了原来的文章,但是总感觉写的很丑,难道必须要用这么难看的方法来解决这个问题吗?想了半天,有没有简单的方法能够解决呢?

思考半天,找到了答案,直接对两个 GeoDataFrame 对象做类似数据库的 join 操作不就可以了嘛,只是任意两个判断的时候用空间操作代替数据库的匹配操作。想到这,就开始翻看 geopandas 的用户手册,果然让我找到了。

解决路径

1. 包引用

from geopandas import *
from shapely.geometry import * 

2. 创建两个 GeoDataFrame 对象

geopandas 可以直接将 shp 文件读为 GeoDataFrame 对象,如下:

shpdata = GeoDataFrame.from_file(path)

此处,采用模拟的方式创建两个 GeoDataFrame 对象,如下:

p1 = Point([1, 2])
p2 = Point([1.5, 1.7])
p3 = Point([1.8, 1.5])
p4 = Point([1.4, 2.2])
gdf1 = geopandas .GeoSeries([p1, p2]).buffer(0.3)
gdf2 = geopandas .GeoSeries([p3, p4]).buffer(0.2)

首先创建4个点对象,使用前两个创建第一个 GeoSeries 对象,后两个创建第二个 GeoSeries 对象。 buffer 函数执行缓冲区分析,将点以一定的距离扩展成面。GeoSeries 简单的说是只包含空间属性的对象,不包含 GeoDataFrame 的其他字段,所以需要为其附加其他字段,为第一个添加 left 字段,为第二个添加 right 字段,并赋值,如下:

gdf1 = GeoDataFrame({"left": [1, 2]}, geometry=gdf1)
gdf2 = GeoDataFrame({"right":[3, 4]}, geometry=gdf2)

两个 GeoDataFrame 如下:

通过画图可以看出两个对象的位置关系:

ax = gdf1.plot(color='red')
gdf2.plot(ax=ax, color='green')

3. 两两相交

官网翻阅半天,找到了 overlay 函数,overlay 是覆盖的意思,从意思我们就能猜测出是对两个对象做覆盖的操作。

官网介绍如下:

When working with multiple spatial datasets – especially multiple polygon or line datasets – users often wish to create new shapes based on places where those datasets overlap (or don’t overlap). These manipulations are often referred using the language of sets – intersections, unions, and differences. These types of operations are made available in the geopandas library through the overlay function. The basic idea is demonstrated by the graphic below but keep in mind that overlays operate at the DataFrame level, not on individual geometries, and the properties from both are retained. In effect, for every shape in the first GeoDataFrame, this operation is executed against every other shape in the other GeoDataFrame:

参考http://geopandas.org/set_operations.html

大意是说当执行两个空间对象的相交、合并、取异操作的时候就可以使用此函数。

此函数可以判断两个空间对象的交集、并集以及不同的部分,此处我们只需要取出交集就可以了。

intersection_data = geopandas.overlay(gdf1, gdf2, how='intersection')

参数 how 设置为 intersection 则取出两组数据相交的部分,结果如下图所示:

绘图如下:

可以看到确实取出了相交的部分,至此我们就得到了想要的结果。

结束

只要是需要判断两组空间对象空间位置的均可以使用此函数,其余的诸如并集、取异等可以自行试验,或参考官方文档。解决问题的途径有很多,而最简单最优美的解决方式总是无止境的,在解决某一实际问题时我们无需过多的思考如何最佳,但是当闲暇时刻静下心来的时候还是应该想想碰到的问题如何解决才是最优的。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏小詹同学

爬点重口味的 。

小弟最近在学校无聊的很哪,浏览网页突然看到一张图片,对面的女孩看过来(邪恶的一笑),让人想入非非啊,一看卧槽,左边这妹子彻底赢了,这(**)这么大,还这么漂亮,...

21920
来自专栏Seebug漏洞平台

libSSH 认证绕过漏洞(CVE-2018-10933)分析

最近出了一个libSSH认证绕过漏洞,刚开始时候看的感觉这洞可能挺厉害的,然后很快github上面就有PoC了,msf上很快也添加了exp,但是在使用的过程中发...

19620
来自专栏崔庆才的专栏

这可能是你见过的最全的网络爬虫干货总结!

昨天的时候我参加了掘金组织的一场 Python 网络爬虫主题的分享活动,主要以直播的形式分享了我从事网络爬虫相关研究以来的一些经验总结,整个直播从昨天下午 1 ...

1.2K60
来自专栏简书专栏

目标检测第1步-运行tensorflow官方示例

在进行本文操作之前,需要先安装好tensorflow的gpu版本。 本文作者的环境:python3.6、Windows10、tensorflow_gpu1.1...

1.3K30
来自专栏北京马哥教育

用Python爬下十几万本小说,再也不会闹书荒!

自从看了师傅爬了顶点全站之后,我也手痒痒的,也想爬一个比较牛逼的小说网看看,于是选了宜搜这个网站,好了,马上开干,这次用的是mogodb数据库,感觉mysql太...

19540
来自专栏Crossin的编程教室

这些年,你们一起踩过的坑(2)

上次我们踩坑总结文章 这些年,你们一起踩过的坑(1) 受到了不少同学的认可。我也确信文中所涉及的问题是非常具有普遍性的,对绝大多数初学者都会有帮助。

13830
来自专栏老九学堂

C 语言:我不是针对谁,我是说在座的都是乐色

从上世纪七十年代开始,许多编程语言都曾受到程序员的青睐。尽管这些语言很好、很有用,但从高级语言开始学习的人在编程知识方面都有许多遗漏。

14720
来自专栏java思维导图

【1024程序员节】致敬所有程序员

2002年,俄罗斯程序员Valentin Balt收集签名,向俄罗斯联邦政府请愿将9月13日设定为程序员节。2009年9月11日,俄罗斯总统梅德韦杰夫在节日安排...

18820
来自专栏人工智能LeadAI

什么!卷积要旋转180度?!

一看这个标题就会想,这有什么大惊小怪的,可能好多人觉得这是个脑残话题,但我确实误解了两三年……

26610
来自专栏Python小屋

《Python程序设计基础与应用》课后习题答案

3.8K40

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励