1

I'm using ArcGIS 10.3, 64bit with an advanced license. I have the following code, that runs just fine. It goes through a table that contains a large number of entries with zip-codes and population information. There are multiple entries for each zip-code. I now want to:

  • Go through the whole table and select each unique zip code one by one and
  • calculate the mean value of the population entries

I therefore created the following script:

import arcpy

# set workspace
workspace = r"Path_to_my_WS"
arcpy.env.workspace = workspace
arcpy.env.scratchworkspace = workspace
arcpy.env.overwriteOutput = True

# set inputs
inputTable = r"Path_to_my_table"
field_zip = "Fieldname_with_zipcodes"
field_pop = "Fieldname_with_population"

# create list with unique zip-codes
zipcodes = [row[0] for row in arcpy.da.SearchCursor(inputTable, field_zip)]
uniqueZipcodes = set(zipcodes)

# MAIN TASK: SUM SALES
# empty list to append values to
pop_avg = []
arcpy.MakeFeatureLayer_management(inputTable, "inputTable_Lyr")
# Loop through unique zip codes and perform statistics analysis
for each_zipcode in uniqueZipcodes:
    where_clause = "field_pop =" + each_zipcode
    arcpy.SelectLayerByAttribute_management("inputTable_Lyr","NEW_SELECTION", where_clause)
    statistics = """{0}\statistics""".format(workspace)
    arcpy.Statistics_analysis("inputTable_Lyr",statistics,[[field_pop,"MEAN"]])
    inquiry_pop_avg = arcpy.da.SearchCursor(statistics,"MEAN_field_pop")
    pop_avg.append(inquiry_pop_avg)
    del statistics
print(uniqueZipcodes)
print(pop_avg)

It does work like this, however it takes a rather long time. Would it be possible to replace the arcpy.Statistics_analysis() function with a more performant version of the arcpy.da.SearchCursor() in order to avoid creating and deleting a table for each loop?

  • 1
    I think it would be much quicker and simpler to use a case_field (field_zip) with Summary Statistics. – PolyGeo Mar 2 '16 at 11:34
5

You can use list comprehensions and cursors to do something like this:

def pop_avg(pop_info):
     zipcode_info = {}
     for zp in pop_info:
         try:
            zipcode_info[zp[0]].append(zp[1])
         except:
            zipcode_info[zp[0]] = [zp[1]]
     return [(key,sum(value)/float(len(value))) for key,value in sorted(zipcode_info.iteritems())]

Using the sample dataset below:

enter image description here

  • populate a list with zip, population pairs.

  • pop_stats = [(row[0],row[1]) for row in arcpy.da.SearchCursor("PopData",["ZIPCODE","POPULATION"])]

  • Call the pop_avg function and pass it pop_stats

  • the sample data produces the results below:

enter image description here

  • The same results can be obtained by simply using summary statistics:

enter image description here

  • This is a great answer. Thanks for all the details provided! – dru87 Mar 2 '16 at 15:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.