Select to view content in your preferred language

Arcpy Check Rows for 2 values and Loop

855
3
11-02-2020 08:11 PM
JordanMiller4
Frequent Contributor

How can I check each row for 2 values [counties & township]? Loop and if they match the dictionaries below, continue the If  True statement  than do something. My script right now is super slow. Processed 2 counties in 3 hours. 

#Import system modules
import arcpy  
from arcpy import env  
import os  
import time

counties = ["RIC",\
"ASD",
"ATB",
"TUS",
"HOL",
"STA",
"SUM",
"CAR",
"TRU",
"WAS",
"FAI",
"COL",
"WAY",
"GEA",
"LAK",
"HOC",
"MRW",
"MAR",
"MAH",
"FRA",
"GUE",
"HAS",
"POR",
"CRA",
"CUY",
"COS"]

townships = ["SANDUSKY",\
"MILTON",
"WELLER",
"MORGAN",
"ORWELL",
"LENOX",
"MONTGOMERY",
"MADISON",
"MIFFLIN",
"WAYNE",
"WALNUT CREEK",
"ROME",
"PERRY",
"PIKE",
"SPRINGFIELD",
"TWINSBURG",
"MONROE",
"SUGAR CREEK",
"TUSCARAWAS",
"AUGUSTA",
"BROWN",
"ORANGE",
"ROSE",
"MESOPOTAMIA",
"WARREN",
"FAIRFIELD",
"MILL",
"SANDY",
"FEARING",
"VIOLET",
"SALEM",
"BUTLER",
"KNOX",
"ADAMS",
"MUSKINGUM",
"SALT CREEK",
"SUGAR CREEK",
"WAYNE",
"WATERFORD",
"WATERTOWN",
"MONTVILLE",
"GREEN",
"MILTON",
"PAINT",
"WOOSTER",
"BAUGHMAN",
"CHESTER",
"CHIPPEWA",
"MADISON",
"PAINESVILLE",
"PERRY",
"CONCORD",
"FALLS",
"NORTH BLOOMFIELD",
"BIG ISLAND",
"GRAND PRAIRIE",
"CANFIELD",
"ELLSWORTH",
"AUSTINTOWN",
"FRANKLIN",
"WESTLAND",
"MADISON",
"MONROE",
"TULLY",
"SCOTT",
"NORTH",
"RIPLEY",
"MARION",
"PLEASANT",
"VALLEY",
"SALT CREEK",
"GREENFIELD",
"AUBURN",
"LIBERTY",
"CHARDON",
"EAST UNION",
"BERLIN",
"NEWBURY",
"PARKMAN",
"PAINT",
"BLOOM",
"HARDY",
"DEERFIELD",
"FRANKLIN",
"TROY",
"ATWATER",
"MECHANIC",
"SUFFIELD",
"WINDHAM",
"JACKSON",
"HAMBDEN",
"WASHINGTON",
"WHETSTONE",
"URBAN",
"URBAN",
"URBAN",
"MANTUA",
"HUNTSBURG",
"MUNSON",
"SOUTHINGTON",
"RANDOLPH",
"PRAIRIE",
"MILTON",
"SUGAR CREEK",
"CLARK",
"CRAWFORD",
"THOMPSON",
"POLK",
"NEWTON",
"URBAN",
"BETHLEHEM",
"FRANKLIN",
"LAWRENCE",
"SPRINGFIELD",
"WARREN",
"HOWLAND",
"FARMINGTON",
"URBAN",
"BRACEVILLE",
"BAZETTA",
"JACKSON",
"BRISTOL",
"URBAN",
"PERRY",
"CANAAN",
"CHAMPION",
"BLOOMFIELD",
"BERLIN",
"BROOKFIELD",
"LAWRENCE",
"MIDDLEFIELD",
"BURTON",
"LEROY",
"HAMILTON"]

mxd = arcpy.mapping.MapDocument("CURRENT")  
df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]  
lyr = arcpy.mapping.ListLayers(mxd, "ohioGrids", df)[0]
           

for lyr in arcpy.mapping.ListLayers(mxd, "*"):  
     if lyr.name == "ohioGrids":
         for a in counties:
             b = "%s" % (a) # 
             #print ("%s" % (b))

             for c in townships:
                  d = "%s" % (c) # 
                  #print ("%s" % (d))
                  
                  arcpy.SelectLayerByAttribute_management("ohioGrids", "CLEAR_SELECTION")
                  cnty = '"COUNTY_CD" = \'%s\'' % b
                  seperator = " AND "
                  twpship =  '"TOWNSHIP_N" = \'%s\'' % c
                  lyr.definitionQuery = cnty + seperator + twpship
                  result1 = arcpy.GetCount_management("ohioGrids")
                  #print('{} has {} records'.format("ohioGrids", result[0]))
                  if result1 > 0:
                      #arcpy.RefreshActiveView()
                      # GetExtent
                      lyr = arcpy.mapping.ListLayers(mxd, 'ohioGrids', df)[0]
                      ext = lyr.getExtent()
                      df.extent = ext
                      # SelectLayerByLocation
                      selection = arcpy.SelectLayerByLocation_management ("Meters", "WITHIN", "ohioGrids")
                      result = arcpy.GetCount_management(selection)
                      count = int(result.getOutput(0))
                      if count > 0:
                           print "COUNTY: " + b + " & " + "TOWNSHIP: " + d
                           print count
                           arcpy.SelectLayerByAttribute_management("ohioGrids", "CLEAR_SELECTION")
                      else:
                           arcpy.SelectLayerByAttribute_management("ohioGrids", "CLEAR_SELECTION")



                           
0 Kudos
3 Replies
DanPatterson
MVP Esteemed Contributor

It is probably slow because you aren't working with dictionaries but two mutually exclusive lists.

If you had a dictionary, then there would be a "key" which you could query and it would return all the possible values for that key.  Right now, you pick something from list "A" and cycle through list "B" even though it is likely that list "B" contains entries that couldn't exist in "A".  There may be overlaps where some values may be associated with multiple keys, but the would be taken of with a true dictionary structure.


... sort of retired...
0 Kudos
DavidPike
MVP Frequent Contributor

scanned through it, can this not be done with a spatial join?

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Beyond a discussion on lists versus dictionaries, something isn't right.  The code is pretty straightforward and simple, so I doubt restructuring the Python data structures will result in much of a change.

I suspect your problem is this line:

selection = arcpy.SelectLayerByLocation_management ("Meters", "WITHIN", "ohioGrids")

Put a print statement with the date and time before and after that operation, see how long it is taking. 

0 Kudos