使用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 则取出两组数据相交的部分,结果如下图所示:

绘图如下:

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

结束

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

原文地址:https://www.cnblogs.com/shoufengwei/p/10046309.html

时间: 2024-10-11 23:31:39

使用Python实现子区域数据分类统计的相关文章

python 学习笔记 3 -- 数据结构篇下

5.引用 当你创建一个对象并给它赋一个变量的时候,这个变量仅仅 引用 那个对象,而不是表示这个对象本身!也就是说,变量名指向你计算机中存储那个对象的内存.这被称作名称到对象的绑定.eg. [python] view plaincopy # -*- coding: utf-8 -*- shoplist = ['apple', 'mango', 'carrot', 'banana'] print "we copy the shoplist to mylist directly \"with

Python下载Yahoo!Finance数据

Python下载Yahoo!Finance数据的三种工具: (1)yahoo-finance package. (2)ystockquote. (3)pandas.

linq根据传入数据集合查询对应子级数据

工作中经常用到的linq根据传入数据集合查询对应子级数据,整理共享,希望大家都能用得上,代码中doublesArray 为父节点对应ID数据集合,再根据ID数据集合查询全部子级数据. //获取缓存数据 object obj = Caching.GetCache(CacheKey + UModel.RoleId); if (obj != null)//判读缓存数据是否null { SysFunList = (DataSet)obj; } else { string strSql = "select

ubuntu10.04 bind9 配置主从区域数据传送问题

今天在ubuntu10.04上配置dns主从区域数据传送时 从服务器学习不到主服务器的配置,查看/var/log/messages时显示为 Aug  1 06:42:45 ubuntu kernel: [ 5397.159601] type=1503 audit(1406900565.661:37):  operation="mknod" pid=2351 parent=1 profile="/usr/sbin/named" requested_mask="

python 学习笔记 3 -- 数据结构篇上

数据结构是可以处理一些 数据 的 结构 .或者说,它们是用来存储一组相关数据的.在Python中有三种内建的数据结构--列表.元组和字典.本文主要对这三种数据类型以及相关的使用做介绍,以例子的形式演示更加容易理解! 1.列表(List) 列表是处理一组有序项目的数据结构,即你可以在一个列表中存储一个 序列 的项目.在Python中,你在每个项目之间用逗号分割. 列表中的项目应该包括在**方括号**中,这样Python就知道你是在指明一个列表.一旦你创建了一个列表,你可以添加.删除或是搜索列表中的

window.open()方法用于子窗口数据回调至父窗口,即子窗口操作父窗口

window.open()方法用于子窗口数据回调至父窗口,即子窗口操作父窗口 项目中经常遇到一个业务逻辑:在A窗口中打开B窗口,在B窗口中操作完以后关闭B窗口,同时自动刷新A窗口(或局部更新A窗口)(或将数据传回A窗口) 以下是从实际项目中截取出来和window.open()方法相关的代码,业务逻辑如下: 1. 点击父窗口的div标签(id="addMatchSchedule"),出发点击事件,打开子窗口: 2. 点击子窗口的button按钮,触发点击时间,即调用addSchduleI

使用python操作elasticsearch实现数据插入分析

前言: 例行公事,有些人可能不太了解elasticsearch,下面搜了一段,大家瞅一眼. Elasticsearch是一款分布式搜索引擎,支持在大数据环境中进行实时数据分析.它基于Apache Lucene文本搜索引擎,内部功能通过ReST API暴露给外部.除了通过HTTP直接访问Elasticsearch,还可以通过支持Java.JavaScript.Python及更多语言的客户端库来访问.它也支持集成Apache Hadoop环境.Elasticsearch在有些处理海量数据的公司中已经

Python将JSON格式数据转换为SQL语句以便导入MySQL数据库

前文中我们把网络爬虫爬取的数据保存为JSON格式,但为了能够更方便地处理数据,我们希望把这些数据导入到MySQL数据库中.phpMyadmin可以把MySQL数据库中的数据导出为JSON格式文件,但却不能把JSON格式文件导入到MySQL数据库.为了实现这个目标,可以编写Python脚本将JSON格式数据转换为SQL语句以便导入MySQL数据库. JSON文件tencent.json部分内容: {"recruitNumber": "1", "name&qu

python打印表格式数据,留出正确的空格和段落星号或注释

python打印表格式数据,留出正确的空格,格式化打出 代码如下: def printPicnic(itemsDict,leftWidth,rightWidth): print('PICNIC ITEMS'.center(leftWidth + rightWidth,'-')) for k,v in itemsDict.items(): print(k.ljust(leftWidth,'.')+str(v).rjust(rightWidth)) picnicItems = {'sandwitch