I have a feature class Test_NearestNeighbor_Code. This feature class has 7373 polygon features and a column/ field called osm_id. I want to do a calculation with all features that have the same osm_id. How can I do this in arcpy in an iterative way over all features (without using the ModelBuilder)?

Calculate Field code works, but loop with SearchCursor doesn't, any suggestions for improvement?

Attached the Attribute Table of the feature class Test_NearestNeigbour_Code.

enter image description here

with arcpy.da.SearchCursor("Test_NearestNeighbour_Code", ["osm_id"]) as cursor:
    for row in cursor:
        arcpy.management.CalculateField("Test_NearestNeighbour_Code", "Dispersitätsmaß", "nn_output[1]", "PYTHON3", 'nn_output = arcpy.stats.AverageNearestNeighbor("Test_NearestNeighbour_Code", "EUCLIDEAN_DISTANCE", "NO_REPORT", None)', "DOUBLE", "NO_ENFORCE_DOMAINS")```
  • Title of your post is misleading.
    – FelixIP
    Mar 16, 2022 at 1:39
  • to determine a spatial dispersion measure that indicates whether sub-areas in a feeder catchment area are more spatially dispersed or clustered.
    – Mr.Zab
    Mar 23, 2022 at 0:18

2 Answers 2


Providing your features have unique id field called "UNIQ_ID" and osm_id is integer field the script below should work.


enter image description here


import arcpy
inLayer = "all_points"
aSet = set(row[0] for row in arcpy.da.TableToNumPyArray(inLayer,"OSM_ID"))
tempFc = "in_memory/selected"
for item in aSet:
    arcpy.AddMessage('Processing item %s' %item)
    arcpy.analysis.Select(inLayer, tempFc, '"osm_id" =%i'%item) #modify query if osm_id is a string
    result = arcpy.stats.AverageNearestNeighbor(tempFc)[1]
    for row in tbl:aDict[row[0]]=result #memorize result in dictionary
arcpy.AddMessage('Results transfer...')
with arcpy.da.UpdateCursor(inLayer,("UNIQ_ID","z_score")) as cursor:
    for oid,z in cursor:cursor.updateRow((oid,aDict[oid]))


enter image description here

  • Hi FelixIP, thank you very much for your very quick reply. I've tried your code several times and I don't understand why some of the polygon (in your code the point) feature with the same osm_id have different z_score values (in my column "Dispersitätsmaß"). Attached is the table and my code for it. Do you have an idea what it could be? I had to convert "osm_id" to the "Double" data type because the numbers of the osm_id were larger than the maximum of the "Long Integer" data type.
    – Mr.Zab
    Mar 20, 2022 at 23:12
  • Your polygons identifiers are not unique.
    – FelixIP
    Mar 21, 2022 at 0:46
  • okay, with the "osm_id_double" as "UNIQID", it works.
    – Mr.Zab
    Mar 23, 2022 at 0:11
  • Is it possible to add the condition that it should only execute it if at least two polygon features have been selected after the command “arcpy. analysis. Select”, maybe in the command “result = arcpy. stats. AverageNearestNeighbor (tempFc) [1]” ? Because the Nearest-Neighbor-analysis need two features
    – Mr.Zab
    Mar 25, 2022 at 21:20
  • Use getCount after Select. If it is less than 2, continue. Read first how getCount works. Modify cursor.updateRow((oid,aDict[oid])) to cursor.updateRow((oid,aDict.get([oid],-1)))
    – FelixIP
    Mar 26, 2022 at 1:04

with > 1, it works with "cursor.updateRow((oid,aDict[oid]))", but with a result in the column "Dispersitätsmaß" of features, which getCount <=1 . For them, it should be no result (), because the calculation should not be carried out. Any suggestions to improve this?

with "cursor.updateRow((oid,aDict.get([oid],-1)))" below, i´ll get this error message

import numpy
inLayer = "Test_NearestNeighbour_Code"
aSet = set(row[0] for row in arcpy.da.TableToNumPyArray(inLayer,"osm_id_zahl_double"))
tempFc = "selected"
for item in aSet:
    arcpy.AddMessage('Processing item %s' %item)
    arcpy.analysis.Select(inLayer, tempFc, '"osm_id_zahl_double" =%i'%item) 
    if int(arcpy.GetCount_management(tempFc).getOutput(0)) > 1 :
        result = arcpy.stats.AverageNearestNeighbor(tempFc)[1]
    for row in tbl:aDict[row[0]]=result
arcpy.AddMessage('Results transfer...')
with arcpy.da.UpdateCursor(inLayer,("osm_id_zahl_double","Dispersitätsmaß")) as cursor:
    for oid,z in cursor:cursor.updateRow((oid,aDict.get([oid],-1)))

TypeError                                 Traceback (most recent call last)
In  [7]:
Line 15:    for oid,z in cursor:cursor.updateRow((oid,aDict.get([oid],-1)))

TypeError: unhashable type: 'list'
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Mar 26, 2022 at 12:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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