-1

I have a polygon feature class with attribute fields 'name', 'rank' and 'area' in an Esri file geodatabase.

For each name there are multiple features (polygons) in the feature class. So let's say 5 polygons named 'Eva', 3 polygons named 'John' and 1 polygon named 'Ernest'. The attribute field 'area' is filled with the area and the attribute field 'rank' is still empty (int).

I want to rank the polygons by size, for every unique name. So the largest polygon for each name to be ranked 1, the second largest polygon 2, etc.

Result: there's a polygon numbered 1 for each John, Ernest and Eva; there's a polygon numbered 2 for John and Eva, there's a polygon number 3 for John and Eva, there's a polygon numbered 4 for Eva and a polygon numbered 5 for Eva. That about it.

Auto incrementing field based on groups within feature class? did the trick filling the rank field with values, but the ranking appeared to be random. Sorting on the area field did not change the situation.

With a bit of Esri help and a colleague we came up with this Python script, which I want to share with you all:

import arcpy
from itertools import count, groupby

layer = "object"
fields = ["name","area", "rank"]
sql = "ORDER BY name, area DESC"

with arcpy.da.UpdateCursor(layer,fields, sql_clause=(None,sql)) as cur:
     for k,g in groupby(cur, key=lambda x: x[0]):
         ctr = count(1)
         for row in g:
             cur.updateRow(row[:-1] + [next(ctr)])
4
  • 1
    There are several different ways to do this, depending on whether you'd prefer Python or a tool, and whether you have an Advanced license, which tool (Summary Stats or Frequency). If the feature class is in an RDBMS, then you have SQL options as well.
    – Vince
    Sep 29, 2020 at 12:06
  • 1
    GIS SE is not a tutorial site. We use a Focused question/Best answer model. See the Tour for more information. Please Edit the question to provide details on what you have tried, and what error you encountered. Welcome to GIS SE.
    – Vince
    Sep 29, 2020 at 13:02
  • 1
    I'd do this in Python, but this can be done with Summary Statistics or Frequency, combined with a join or relate, and a Calculate Field. There's probably a number of similar solutions already posted, but complete solutions to something this specific are rare.
    – Vince
    Sep 29, 2020 at 14:23
  • 1
    Sort by area in descending order and populate rank by script from gis.stackexchange.com/questions/200150/…
    – FelixIP
    Sep 29, 2020 at 19:12

1 Answer 1

2

I have to repeat such task few times a day, so I developed a script (not shown) and also field calculator expression below:

lr="a"
tbl=arcpy.da.TableToNumPyArray(lr,("fid","Length","strmOrder"))
bs=sorted(tbl, key=lambda x: (x[1]),reverse=False)
dPid={}
d={}
for row in bs:
 N=dPid.get(row[2],0);N+=1
 dPid[row[2]]=N
 d[row[0]]=N
def SortGroupOrder(oid):
  return d[oid]

#--------
SortGroupOrder( !FID!)

You'll need to replace field names (e.g. Length to Area and strmOrder to Owner), and reverse=False to reverse=True and also name your layer "a" unless you'd like to hardcode it as well. You also need to change OID name, if data are not stored in shapefile.

Run it on your Rank field.

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