Python批量计算上市公司距离边界的距离

该文描述了使用ArcGIS和geopandas库来处理地理空间数据,目的是计算位于上海、北京等7个省市及相邻区域企业的办公地址与边界之间的垂直距离。首先进行数据预处理和投影转换,然后利用GeoDataFrame的几何对象方法计算点到多边形边界的最短距离。文章提到了在处理过程中遇到的索引不匹配问题以及解决方案,并给出了部分代码示例。
摘要由CSDN通过智能技术生成

具体工作内容:
需要定位上海,北京,广东省,天津,湖北省,重庆,福建省内外边界的企业,得到这些企业距离边界的垂直距离。企业范围为上述7个省市+7个省市相邻的省市的企业。

已有数据:
上市公司excel文件(坐标格式为wgs1984)
办公地址的shp文件
注册地址的shp文件

输出格式:csv
字段:股票代码,股票名称,公司地址,是否是办公地址(1为是,0为否)、省份、距离哪一个省市的边界(例如,湖北省),距离边界的距离(单位:米)

一、arcgis数据预处理

预处理也可以用Python写,这里为了可视化了解数据就在Arcgis Pro中完成。

  1. 将省市边界和公司 统一投影到 WGS_1984_UTM_Zone_46N 以计算距离
  2. 定位七个省市 内外边界的企业

image.png

  1. 提取给定范围内的公司

image.png

  1. 股票代码去重

有些公司股票代码重复出现,如果地址是一样的,可当做同一家公司,在输出文件中占一行即可。

image.png

二、geopandas函数

距离实例

from shapely.geometry import Point
from shapely.geometry import LineString
point = Point([1,1])
line = LineString(((0,0), (1,1), (1,0)))
dist = point.distance(line)
h_dist = point.hausdorff_distance(line)
print(dist)
print(h_dist)

GeoDataFrame对象的空间拓扑分析方法包括contains()、within()、crosses()、intersects()等,参数是指定的几何对象,返回类型为布尔值的Series对象。

Bug:The indices of the two GeoSeries are different
解决方案:https://gis.stackexchange.com/questions/375407/geopandas-intersects-doesnt-find-any-intersection

例子可视化方案,耗时长,不适合批处理:https://medium.com/analytics-vidhya/calculating-distances-from-points-to-polygon-borders-in-python-a-paris-example-3b597e1ea291
在这里插入图片描述

三、完整代码

#读取shp
import geopandas as gpd
import pandas as pd
import numpy as np
boundry = gpd.read_file(r'七省及其边界_20\七省及其边界_20.shp',
                    encoding="utf8")
office_addr = gpd.read_file(r'办公地址_utm_七省内外边界\办公地址_utm_七省内外边界.shp',
                    encoding="utf8")
                    
#使boundry 省份名和shp同步
boundry['省'] = boundry['省'].str[:2]

#可视化
ax1 = office_addr.plot(color="r",markersize=4)
boundry.plot(ax=ax1,color="gray",zorder=0)

#数据处理
result =pd.DataFrame(columns=('股票名称','股票代码','公司地址','省份','是否是办公地址','距离哪一个省市的边界','距离边界的距离'))
#将计算结果逐行插入result,注意变量要用[]括起来,同时ignore_index=True,否则会报错,ValueError: If using all scalar values, you must pass an index

#遍历公司,所在及相邻多边形 最短距离
for index,row in office_addr.iterrows(): # Looping over all points
    #扩展检索省份
    newdf = gpd.GeoDataFrame(np.repeat(boundry[boundry['省']==row['省份']].values, 20, axis=0), columns=boundry.columns)
    newdf = newdf.set_crs(32646)
    shares_boundary = boundry[boundry.geometry.intersects(newdf)] #肯定有所在省份和至少一个相邻省份

    # Calculating dist for the neighbor polygon
    for index2,row2 in shares_boundary.iterrows():
        # for target in shares_boundary:
        dist = gpd.GeoSeries(row2.geometry).boundary.distance(gpd.GeoSeries(row.geometry)).values[0]
        result=result.append(pd.DataFrame(
            {'股票名称':[row['股票名']],'股票代码':[row['股票代']],'公司地址':[row['办公地']],'是否是办公地址':1,'省份':[row['省份']],'距离哪一个省市的边界':[row2['省']],'距离边界的距离':[dist]} #variable 要加[]
            ),ignore_index=True)
result.to_csv('办公地址result.csv')

注册地址同理

四、工作时间

3.1
21:00-22:00 数据准备 投影

3.2
11:30-2:30 遍历点,所在及相邻多边形 最短距离 思路整理
17:00-18:00 arcgis脚本开发
20:00-23:00 内置modelbuiler构建尝试失败,bug太多,不如代码灵活

3.3
9:00-11:00 编写geopandas代码+运行

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值