DataFrame与shp文件相互转换

Stella981
• 阅读 1548

因为习惯了使用pandas的DataFrame数据结构,同时pandas作为一个方便计算和表操作的数据结构具有十分显著的优势,甚至很多时候dataFrame可以作为excel在使用,而在用python操作gis的shp文件时很不顺畅,不太符合使用习惯,故写了一个DataFrame与arcgis地理文件相互转换的函数,这个处理起来可以节约大量的思考时间。

Shp转DataFrame:

import arcpy
import pandas as pd

def Shp2dataframe(path):
    '''将arcpy表单变为pandas表单输出'''
    fields=arcpy.ListFields(path)
    table=[]
    fieldname=[field.name for field in fields]
    #游标集合,用for 循环一次后没办法循环第二次!一个游标实例只能循环一次
    data=arcpy.SearchCursor(path)
    for row in data:
        #Shape字段中的要数是一个几何类
        r=[]
        for field in fields:
            r.append(row.getValue(field.name))
        table.append(r)
    return pd.DataFrame(table,columns=fieldname)

DataFrame转Shp:

DataFrame转Shp采用了模板形式,通过模板建立字段文件,坐标系等可以更加快速构建字段。

#将由ReadTable读取的pandas表转换为shp格式,template为模板
def Dataframe2ShpTemplate(df,outpath,geoType,template):
    '''
    Fuction:
    make the table of pandas's DataFrame convert to the shp of esri
    Input:
    df -- pandas DataFrame from the shp converted
    outpath -- the shp output path
    geometryType -- the type of geomentey, eg:'POINT','POLYLINE','POLYGON','MULTIPOINT'
    temple -- the temple, at most time it is used the DataFrame's shp
    '''
    out_path = outpath.replace(outpath.split('/')[-1],'')
    out_name = outpath.split('/')[-1]
    geometry_type = geoType
    #template为模板,可以将里面属性全部赋予新建的要素,包括字段、坐标系
    feature_class = arcpy.CreateFeatureclass_management(
        out_path, out_name, geometry_type, template)
    #'*'表示插入所有字段,但如果不用模板容易产生位置不对等
    #cursor = arcpy.da.InsertCursor(outpath,'*')
    for row in df.index:
        #Shape需要改为'SHAPE@'才可以写入
        df['SHAPE@'] = df['Shape']
        cursor = arcpy.da.InsertCursor(outpath,[field for field in df.columns])
        cursor.insertRow([df[field][row] for field in df.columns])
    print 'Pandas to shp finish!'
    del cursor

实例应用:

写一个根据gps公交点Txt构建shp数据代码,代码如下:

def readDataFile(filetype,filename,savefile):
    #用'gbk'编码读取,读取成统一编码的unicode
    with codecs.open(filename,encoding='gbk') as datafile:
        
        #以列表形式读取所有文件
        pointData = datafile.readlines()
        #第一行删除并返回为title
        outputFileName = 'bus'+re.findall('[0-9]*[0-9]',filename)[0]+filetype
        #检查是否导出文件重复
        saveEnv = arcpy.Describe(savefile)
        for child in saveEnv.children:
            if child.name == outputFileName:
                outputFileName = outputFileName + '_1'
        print 'output path is %s'%(savefile+outputFileName)
        #设置shp文件模板
        template = u'./dealing/temple.gdb/%s'%filetype
        linename = filename.strip('./dealing\\').decode('gbk').encode('utf-8')
        if filetype == 'point':
            df = pd.DataFrame(columns=Shp2dataframe(template).columns)
            for num in xrange(len(pointData)):
                row = pointData[num].strip('\r\n').split(' ')
                
                df.set_value(num,'name',row[0])
                df.set_value(num,'x',row[1])
                df.set_value(num,'y',row[2])
                df.set_value(num,'line',linename.strip('point.txt'))
                
                point = arcpy.PointGeometry(arcpy.Point(row[1],row[2]))
                df.set_value(num,'Shape',point)
                
        elif filetype == 'line':
            df = pd.DataFrame(columns=Shp2dataframe(template).columns)
            pointList = []
            #构建线集合
            for eachPoint in pointData:
                coord = eachPoint.strip('\r\n').split(' ')
                pointList.append(arcpy.Point(float(coord[0]),float(coord[1])))
            df.set_value(0,'name',linename.strip('line.txt'))
            #组建线要素arcpy.Polyline(arcpy.Array(pointList))
            df.set_value(0,'Shape',arcpy.Polyline(arcpy.Array(pointList)))
    
    Dataframe2ShpTemplate(df,savefile+outputFileName,'',template)
    return df

-------sugar---------------------sugar--------------------sugar-------------------sugar----------------sugar----------

#搜索目录下的所有带point.txt和line.txt的文件

pointfiles = glob.glob('./dealing/*point.txt')
polylinefiles = glob.glob('./dealing/*line.txt')

for pf in pointfiles:
    print pf
    readDataFile('point',pf,u'dealing/广州市道路网.gdb/')

for pl in polylinefiles:
    print pl
    df=readDataFile('line',pl,u'dealing/广州市道路网.gdb/')


lineshp = arcpy.Describe(u'dealing/广州市道路网.gdb/')
linelist = []
for child in lineshp.children:
    if 'line' in child.name:
        linelist.append(u'dealing/广州市道路网.gdb/'+child.name)
arcpy.Merge_management(linelist,u'dealing/广州市道路网.gdb/0allLine')

Kanonpy

http://my.oschina.net/Kanonpy/admin/edit-blog?blog=425633

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Wesley13 Wesley13
3年前
java将前端的json数组字符串转换为列表
记录下在前端通过ajax提交了一个json数组的字符串,在后端如何转换为列表。前端数据转化与请求varcontracts{id:'1',name:'yanggb合同1'},{id:'2',name:'yanggb合同2'},{id:'3',name:'yang
CuterCorley CuterCorley
3年前
Python数据分析实战(2)使用Pandas进行数据分析
一、Pandas的使用1.Pandas介绍Pandas的主要应用包括:数据读取数据集成透视表数据聚合与分组运算分段统计数据可视化Pandas的使用很灵活,最重要的两个数据类型是DataFrame和Series。对DataFrame最直观的理解是把它当成一个Excel表格文件,如下:索引是从0开始的,也
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
3个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
黎明之道 黎明之道
3年前
Pandas数据载入与预处理(详细的数据Python处理方法)
Pandas数据载入与预处理对于数据分析而言,数据大部分来源于外部数据,如常用的CSV文件、Excel文件和数据库文件等。Pandas库将外部数据转换为DataFrame数据格式,处理完成后再存储到相应的外部文件
Stella981 Stella981
3年前
Python 数据分析包:pandas 基础
pandas是基于Numpy构建的含有更高级数据结构和工具的数据分析包类似于Numpy的核心是ndarray,pandas也是围绕着Series和DataFrame两个核心数据结构展开的。Series和DataFrame分别对应于一维的序列和二维的表结构。pandas约定俗成的导入方法如下:lang:pytho
Stella981 Stella981
3年前
Python3环境通过JDBC访问非Kerberos环境的Hive
1.文档编写目的在前面Fayson介绍了在Python2的环境下《如何使用PythonImpyla客户端连接Hive和Impala》,本篇文章Fayson主要介绍在Python3的环境下使用Impyla访问非Kerberos环境下的Hive以及将获取到的结果集转换为Pandas的DataFrame。内容
Python进阶者 Python进阶者
9个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
桥蕤 桥蕤
5个月前
Pandas-DataFrame
DataFrameDataFrame是Pandas的一种数据类型可以理解为n乘n的表格结构;下面是它的部分常用用法1.创建DataFramepythonimportpandasaspdimportnumpyasnpdictpd.DataFrame(data