# Python Group by attribute range

I have about 6000 points that I need to run a computationally intensive analysis on. My thought process is to break this point layer up into six groups of 1000 points each. I'm trying to do this in ArcGIS ModelBuilder in 10.5 using the field calculator tool. The grouping doesn't really matter, but all of the other attributes to use (city, state, zip) will overwhelmingly put more points into one category and not the other 5 because they are spatially clustered. My plan was to use either the ObjectID, or the unique ID field I created (ObjectID number + letter "A")

My code is as follows:

def classify(OBJECTID) :
if int(OBJECTID) >= 5000 :
return 6
elif int(OBJECTID) >= 4000  and int(OBJECTID) <= 4999 :
return 5
elif int(OBJECTID) >= 3000  and int(OBJECTID) <= 3999 :
return 4
elif int(OBJECTID) >= 2000  and int(OBJECTID) <= 2999 :
return 3
elif int(OBJECTID) >=1000 and int(OBJECTID) <= 1999 :
return 2
else:
return 1

classify(!Group_!)


However this code is giving all of my points a value of 1. I can't figure out why. I've also tried this with the int() portions of code removed and tried using a range statement int(OBJECTID) in range (4000, 4999): .

Can anyone help? • Can you show your OBJECTIDs? Do they contain trailing or leading spaces? One thing you could do is to print(int(OBJECTID)) to see what values are actually being compared against.
– Jon
Oct 16, 2018 at 19:12
• Sure thing @Jon, I've provided a screenshot of the attribute table from ArcMap.
– BenW
Oct 16, 2018 at 19:16
• Hm, try the print statement to make sure you're passing in what you intend.
– Jon
Oct 16, 2018 at 19:21
• Also looks like ObjectIDs in Arc are stored as unique integers desktop.arcgis.com/en/arcmap/latest/manage-data/…
– BenW
Oct 16, 2018 at 19:22
• Try classify(! objectid!) Oct 16, 2018 at 19:25

It looks like you're passing your group field into your function instead of ObjectID. Be sure to pass in the ObjectID. Then make use of an Update Cursor to update your Group_ field.

fc = r"path\to\feature\class"

#----------

import arcpy

def classify(OBJECTID) :
if int(OBJECTID) >= 5000 :
return 6
elif int(OBJECTID) >= 4000  and int(OBJECTID) <= 4999 :
return 5
elif int(OBJECTID) >= 3000  and int(OBJECTID) <= 3999 :
return 4
elif int(OBJECTID) >= 2000  and int(OBJECTID) <= 2999 :
return 3
elif int(OBJECTID) >=1000 and int(OBJECTID) <= 1999 :
return 2
else:
return 1

with arcpy.da.UpdateCursor (fc, ["OID@", "Group_"]) as curs:
for oid, group in curs:
group = classify (oid)
curs.updateRow ((oid, group))


You can also use Calculate Field.

fc = r"path\to\feature\class"

#----------

import arcpy

codeblock = """def classify(OBJECTID) :
if int(OBJECTID) >= 5000 :
return 6
elif int(OBJECTID) >= 4000  and int(OBJECTID) <= 4999 :
return 5
elif int(OBJECTID) >= 3000  and int(OBJECTID) <= 3999 :
return 4
elif int(OBJECTID) >= 2000  and int(OBJECTID) <= 2999 :
return 3
elif int(OBJECTID) >=1000 and int(OBJECTID) <= 1999 :
return 2
else:
return 1"""

oidFld = arcpy.Describe (fc).OIDFieldName
arcpy.CalculateField_management (fc, "Group_", "classify (!{}!)".format (oidFld),
"PYTHON_9.3", codeblock)


Results: 