AnsweredAssumed Answered

Optimizing field updates using multiple feature classes and cursors

Question asked by gardta on May 23, 2017

I am trying to update a field (UNIQUE_SUB_COUNT_13_8) in a (point) feature class (e.g. subLayer) using attributes and spatial relationships to another (line) feature class. For this, I'm currently leveraging arcpy tools, selections, and an update cursor. This section is currently taking over 30 minutes to run. The subLayer feature class contains 7000 records and transLayer contains 7500 records; so these aren't massive feature classes, though they are continually growing as they are developed. Any suggestions on how to optimize this code?

 

I do want to update each row with a value specific to that row. I am wondering if indexing or dictionaries may be of value. A spatial join may also be a better route. However, this script is part of an over a 1000 line script with similar block structures as this for many varying field updates based on varying attribute and spatial relationships among three feature classes (included here for reference: Optimizing a Script Using Python Cursors and Dictionaries ). It would be helpful if the search distance and attribute parameters in the selections can be easily modified. The script was originally built largely utilizing Model Builder and was highly dependent on spatial joins. I have been trying to move to a more streamlined and optimized script that can be more easily edited and adaptive to changes within the source datasets. So far the new script has all the functionality of the model builder code, but is MUCH slower. This section of the script seems like a good place to start with optimization.

 

I will appreciate any tips anyone may have! Thanks! 

 

import arcpy
from arcpy import env
import time
start = time.time()

arcpy.env.OverwriteOutput = True

defaultGdbPath = 'C:\Topo_Check_V5.gdb'


subLayer='C:\Topo_Check_V5.gdb\Subs' #point feature class
transLayer='C:\Topo_Check_V5.gdb\TLS' # line feature class
ppLayer='C:\Topo_Check_V5.gdb\PPS' #point feature class

#######################################################################

#add in UNIQUE_SUB_COUNT_13_8 field
arcpy.AddField_management(subLayer, "UNIQUE_SUB_COUNT_13_8", "SHORT", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")

UNIQUE_SUB_COUNT_13_8 = "UNIQUE_SUB_COUNT_13_8" 


# Make feature layer
arcpy.MakeFeatureLayer_management(transLayer, "transLayer_uniquesubs")

arcpy.AddField_management("transLayer_uniquesubs", "SUB1SUB2", "TEXT", "", "", "", "", "NULLABLE", "NON_REQUIRED", "")

arcpy.CalculateField_management ("transLayer_uniquesubs", "SUB1SUB2", ' [SUB_1] + "," + [SUB_2] ')


#where clause
where_unique_13_8 = ' "VLTS" = 13.8 '

result=int(arcpy.GetCount_management("transLayer_uniquesubs").getOutput(0))

with arcpy.da.UpdateCursor (subLayer, [UNIQUE_SUB_COUNT_13_8, "SHAPE@"]) as UNIQUE_SUB_COUNT_13_8_List:
    for subrow in UNIQUE_SUB_COUNT_13_8_List:
      
        arcpy.SelectLayerByLocation_management("transLayer_uniquesubs", 'WITHIN_A_DISTANCE', subrow[1], .000002, "NEW_SELECTION")
        arcpy.SelectLayerByAttribute_management ("transLayer_uniquesubs", "SUBSET_SELECTION", where_unique_13_8)
        arcpy.DeleteIdentical_management("transLayer_uniquesubs", ['SUB1SUB2'])
       
        subrow[0] = result
        UNIQUE_SUB_COUNT_13_8_List.updateRow(subrow)
print "UNIQUE_SUB_COUNT_13_8 Updated"

########################################################################

end = time.time()
print (end - start)/60

Outcomes