Is there a way to calculate a sorted field with sequential numbers? I have seen Sorting feature class to calculate sequential ID field using ArcGIS Field Calculator? that outlines how to calculate sequential numbers, but this is always calculated on FID order, not on sorted order.
#Pre-logic Script Code:
rec=0
def autoIncrement():
global rec
pStart = 1
pInterval = 1
if (rec == 0):
rec = pStart
else:
rec += pInterval
return rec
#Expression:
autoIncrement()
An example of what I'm trying to do. I've used an advanced sort to sort by year, month, day, and now want to have sequential numbers in the Seq
field. You'll see that my OBJECTID
field is not in order, so the above code won't work.
Can this be done either in the Field Calculator or using an Update Cursor in arcpy?
Answer
"Solution" with 2 sorted fields (ascending):
mxd = arcpy.mapping.MapDocument("CURRENT")
lr=arcpy.mapping.ListLayers(mxd)[0]
tbl=arcpy.da.TableToNumPyArray(lr,("oid","A","B"))
bs=sorted(tbl, key=lambda x: (x[1], x[2]))
def sortSeq(fid,a,b):
for i,ent in enumerate(bs):
if ent[0]==fid: return i
sortSeq( !OID!, !A!, !B! )
UPDATED VERSION:
mxd = arcpy.mapping.MapDocument("CURRENT")
lr=arcpy.mapping.ListLayers(mxd)[0]
tbl=arcpy.da.TableToNumPyArray(lr,("oid","A","B"))
bs=sorted(tbl, key=lambda x: (x[1], x[2]))
aDict={}
for i,row in enumerate(bs):
aDict[row[0]]=i
def sortSeq(fid):
return aDict[fid]
sortSeq( !OID!)
takes 1.5 seconds to complete task on 10000 records. Original takes slightly more than 2 minutes
No comments:
Post a Comment