首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >更新ArcPy特征类

更新ArcPy特征类
EN

Code Review用户
提问于 2015-11-20 10:59:21
回答 1查看 198关注 0票数 1

我正在寻找加速我的剧本的方法。最终的输出是需要的,但是它很笨重,而且速度很慢。我知道这很慢,因为双for..in..循环。那么,我怎样才能让它变得更流畅呢?

我的脚本更新了现有的特征类。我有两个文件夹,其中所有最新的形状文件(shp)存储。我的脚本检查每个文件夹中的shps,然后在4个地理数据库中搜索相同的命名特性类(这些是旧版本)。因此,shp必须转到已经包含相同名称的功能类的gdb。我希望它足够简单。为了让你知道,运行这个脚本需要一个多小时,我有大约45个shapefiles (~1gb),这些文件被复制到4个地理数据库中。

有没有办法避免这些耗时的双for..in..循环?我需要指出的是,文件夹存储在与gdb不同的服务器上,这也是其速度慢的主要原因。当我只使用C驱动器测试脚本时,花费了6-8分钟!

代码语言:javascript
复制
import time
import arcpy


startTime = time.clock()

print "Start"

FCProducts = r"C:\Python\DataConversion\shapefiles"
GBProducts = r"C:\Python\DataConversion\shapefile_gp"
adminBdry = r"C:\Python\DataConversion\temp1.gdb"
GnR = r"C:\DataConversion\temp2.gdb"
Invenories = r"C:\Python\DataConversion\temp3.gdb"
NFE = r"C:\Python\DataConversion\temp4.gdb"


arcpy.env.overwriteOutput = True

arcpy.env.workspace = FCProducts
listFC = [0]
listFC = arcpy.ListFeatureClasses()
del arcpy.env.workspace

for product in listFC:
    f2fOutput = product[:-4] + "_new"

    arcpy.env.workspace = GnR
    listGnrFC = arcpy.ListFeatureClasses()
    for gnrFC in listGnrFC:
        if gnrFC == product[:-4]:
            arcpy.FeatureClassToFeatureClass_conversion(product[:-4], GnR, f2fOutput)
            print product, " copied to ", GnR
            arcpy.Delete_management(gnrFC)
            print "old ", gnrFC, " deleted"
            arcpy.Rename_management(f2fOutput, product[:-4])
            print "output renamed", "\n"

    arcpy.env.workspace = adminBdry
    listAdBdryFC = arcpy.ListFeatureClasses()
    for AdBdry in listAdBdryFC:
        if AdBdry == product[:-4]:
            arcpy.FeatureClassToFeatureClass_conversion(product[:-4], adminBdry, f2fOutput)
            print product, " copied to ", adminBdry
            arcpy.Delete_management(AdBdry)
            print "old ", AdBdry, " deleted"
            arcpy.Rename_management(f2fOutput, product[:-4])
            print "output renamed", "\n"

    arcpy.env.workspace = Invenories
    listInventFC = arcpy.ListFeatureClasses()
    for invent in listInventFC:
        if invent == product[:-4]:
            arcpy.FeatureClassToFeatureClass_conversion(product[:-4], Invenories, f2fOutput)
            print product, " copied to ", Invenories
            arcpy.Delete_management(invent)
            print "old ", invent, " deleted"
            arcpy.Rename_management(f2fOutput, product[:-4])
            print "output renamed", "\n"

    arcpy.env.workspace = NFE
    listNfeFC = arcpy.ListFeatureClasses()
    for nfe in listNfeFC:
        if nfe == product[:-4]:
            arcpy.FeatureClassToFeatureClass_conversion(product[:-4], NFE, f2fOutput)
            print product, " copied to ", NFE
            arcpy.Delete_management(nfe)
            print "old ", nfe, " deleted"
            arcpy.Rename_management(f2fOutput, product[:-4])
            print "output renamed", "\n"

arcpy.env.workspace = GBProducts
listFCgb = [0]
listFCgb = arcpy.ListFeatureClasses()

for productGB in listFCgb:
    f2fOutputGB = productGB[:-4] + "_new"
    arcpy.env.workspace = Invenories
    listInventGB = arcpy.ListFeatureClasses()
    for InventGB in listInventGB:
        if InventGB == productGB[:-4]:
            arcpy.FeatureClassToFeatureClass_conversion(productGB[:-4], Invenories, f2fOutputGB)
            print productGB, " copied to ", Invenories
            arcpy.Delete_management(InventGB)
            print "old ", InventGB, " deleted"
            arcpy.Rename_management(f2fOutputGB, productGB[:-4])
            print "output renamed", "\n"

    arcpy.env.workspace = NFE
    listNfeGB = arcpy.ListFeatureClasses()
    for nfeGB in listNfeGB:
        if nfeGB == productGB[:-4]:
            arcpy.FeatureClassToFeatureClass_conversion(productGB[:-4], NFE, f2fOutputGB)
            print productGB, " copied to ", NFE
            arcpy.Delete_management(nfeGB)
            print "old ", nfeGB, " deleted"
            arcpy.Rename_management(f2fOutputGB, productGB[:-4])
            print "output renamed", "\n"
print "completed within:", time.clock() - startTime, "seconds", "\n"

我正在使用Windows,ArcGis 10.0,Python2.6.6

EN

回答 1

Code Review用户

回答已采纳

发布于 2015-11-20 12:54:28

,不要重复,

首先,最不重要的是,Python花费更多的时间构建子字符串,而不是局部变量查找。因此,您可以通过在循环开始时命名product[:-4]来稍微改进一些。

更重要的是,大多数代码都是相似的:

  • 设置一个新的工作空间;
  • 用它建立一个类的列表;
  • 对于这些类中的每一个:
    • 转换类;
    • 删除旧的;
    • 重新命名新的。

唯一需要更改的是:工作区的名称和所涉及的产品的名称。只需编写一个函数来处理它一次:

代码语言:javascript
复制
import arcpy


FCProducts = r"C:\Python\DataConversion\shapefiles"
GBProducts = r"C:\Python\DataConversion\shapefile_gp"
adminBdry = r"C:\Python\DataConversion\temp1.gdb"
GnR = r"C:\DataConversion\temp2.gdb"
Invenories = r"C:\Python\DataConversion\temp3.gdb"
NFE = r"C:\Python\DataConversion\temp4.gdb"

arcpy.env.overwriteOutput = True

def convert_class(workspace, product_name, output_name):
    arcpy.env.workspace = workspace
    for product in arcpy.ListFeatureClasses():
        if product == product_name:
            arcpy.FeatureClassToFeatureClass_conversion(product_name, workspace, output_name)
            print product_name, " copied to ", workspace
            arcpy.Delete_management(product)
            print "old ", product, " deleted"
            arcpy.Rename_management(output_name, product_name)
            print "output renamed", "\n"

arcpy.env.workspace = FCProducts
listFC = arcpy.ListFeatureClasses()

for product in listFC:
    f2fOutput = product[:-4] + "_new"
    product_name = product[:-4]
    convert_class(GnR, product_name, f2fOutput)
    convert_class(adminBdry, product_name, f2fOutput)
    convert_class(Invenories, product_name, f2fOutput)
    convert_class(NFE, product_name, f2fOutput)

arcpy.env.workspace = GBProducts
listFCgb = arcpy.ListFeatureClasses()

for productGB in listFCgb:
    f2fOutputGB = productGB[:-4] + "_new"
    product_name = productGB[:-4]
    convert_class(Invenories, product_name, f2fOutput)
    convert_class(NFE, product_name, f2fOutput)

节省资源使用

既然代码更容易阅读,那么它到底在做什么呢?对于每个项目,您要切换工作空间2或4次。切换工作区含义:

  • 打开文件;
  • 读它;
  • 解析它;
  • 用它构建数据结构。

即使对每个项目执行一次,也是对时间和计算资源的巨大浪费。最好打开一个工作区一次,迭代每个产品,然后切换到另一个工作区。单个工作区的代码布局如下所示:

代码语言:javascript
复制
def process_workspace(workspace, products):
    arcpy.env.workspace = workspace
    for product in products:
        product_name = product[:-4]
        output_name = product_name + "_new"
        for item in arcpy.ListFeatureClasses():
            if item == product_name:
                arcpy.FeatureClassToFeatureClass_conversion(product_name, workspace, output_name)
                print product, " copied to ", workspace
                arcpy.Delete_management(item)
                print "old ", item, " deleted"
                arcpy.Rename_management(output_name, product_name)
                print "output renamed\n"

然后,只需在每次*.gdb处理之前更改一次工作区:

代码语言:javascript
复制
arcpy.env.workspace = FCProducts
listFC = arcpy.ListFeatureClasses()
process_workspace(GnR, listFC)
process_workspace(adminBdry, listFC)
process_workspace(Invenories, listFC)
process_workspace(NFE, listFC)

arcpy.env.workspace = GBProducts
listGB = arcpy.ListFeatureClasses()
process_workspace(Invenories, listGB)
process_workspace(NFE, listGB)

您甚至可以在工作区上使用for循环来改进布局。

把所有的东西放在一起,

通过在PEP8上加入更多的在线长度和变量命名,我们可以得到以下结果:

代码语言:javascript
复制
import arcpy

FC_PRODUCTS = r"C:\Python\DataConversion\shapefiles"
GB_PRODUCTS = r"C:\Python\DataConversion\shapefile_gp"

ADMIN_BOUNDARY = r"C:\Python\DataConversion\temp1.gdb"
GNR = r"C:\DataConversion\temp2.gdb"
INVENORIES = r"C:\Python\DataConversion\temp3.gdb"
NFE = r"C:\Python\DataConversion\temp4.gdb"


def process_workspace(workspace, products):
    arcpy.env.workspace = workspace
    for product in products:
        product_name = product[:-4]
        output_name = product_name + "_new"
        for item in arcpy.ListFeatureClasses():
            if item == product_name:
                arcpy.FeatureClassToFeatureClass_conversion(
                    product_name, workspace, output_name)
                print product, " copied to ", workspace
                arcpy.Delete_management(item)
                print "old ", item, " deleted"
                arcpy.Rename_management(output_name, product_name)
                print "output renamed\n"

arcpy.env.workspace = FC_PRODUCTS
products = arcpy.ListFeatureClasses()
for workspace in (GNR, ADMIN_BOUNDARY, INVENORIES, NFE):
    process_workspace(workspace, products)

arcpy.env.workspace = GB_PRODUCTS
products = arcpy.ListFeatureClasses()
for workspace in (INVENORIES, NFE):
    process_workspace(workspace, products)
票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/111313

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档