I would like to group values in a field in an attribute table. The field contains duplicate values. These duplicate values should be grouped based on duplicate values, the field would look something like the arbitrary 'Field' below:

Field   Date    Flagged_Field
X      1/1/2014 
X      1/1/2013 
X      1/1/2015    Y
Y      1/1/2000 
Y      1/1/2008    Y
Z      1/1/1999 
Z      1/1/1998 
Z      1/1/1992 
Z      1/1/2003    Y

Values X, Y and Z which are duplicate records would then be grouped. Ideally I would like to proceed to use if, elif and else to compare other fields within the group containing the value X for Field and once finished move on to the group contain the value Y and lastly Z.

Here's what I have:

cursor = arcpy.SearchCursor(fc)
row = cursor.next()
for row in cursor:
    rowField = (row.getValue("Field"))
    listC = ([list(j) for i, j in groupby(rowField)])
    for groups in listC:
        print str(groups)

What happens is I get a list of unicode for each letter in the field. I believe if I can somehow compare the field values against each other as opposed to the characters in just one field I can get close to what I need with this.

I'm trying to gather all like values based on attributes, specifically one field. I would then like to, using these like values compare other attributes of the data. For example I have a date field which, based on like values in the Field shown in my above example I would like to flag the record containing the most recent date, see revisions above.

  • 1
    I think you should use Summary Statistics first and then the subsequent processing will be much simplified, but it is hard to give concrete advice without seeing a few sample rows from your input and expected output. – PolyGeo Sep 9 '15 at 21:47
  • 1
    How do you want to group your rows? What happens with values in other columns? – Alex Tereshenkov Sep 10 '15 at 5:59
  • 1
    I don't understand what you want to do. Your cursor returns a single row, so you cannot "group" it. On the other hand, duplicate are already "grouped by duplicate values" in the sense that they can be identified with this value (sorting would be enough). Are you trying to extract a list of duplicates ? Are you trying to compute statistics for your groups (=summary statistics) ? Are you trying to put all duplicates into a single geometry (=dissolve) ? Note that if you want to manipulate your feature class as a Python list, you should work with ".da" cursors – radouxju Sep 10 '15 at 6:35
  • Summary Statistics would work as @PolyGeo mentioned however, I need to compare several other fields within the like value group. – standard Sep 10 '15 at 14:04

I think I understand what you want to do. For each unique value in "Field", you want to find the most recent date in "Date" and set its value to "Y" in "Flagged_Field".
I used your field naming conventions, but you need to avoid using keywords like Field and Date for your field names.

import itertools

def getGrouper(row):
    """Key function to retrieve Field value. Change depending on how you group"""
    return row[0]
def getDate(row):
    """Key function to retrieve Date value. Used in mapping function below"""
    return row[1]
def mostRecentDate(group):
    """Mapping function for retrieving row in each group with most recent date"""
    return max(group, key=getDate)

# I define up here to avoid hard coding into body of script
fc = "YourFeatureClass"
# Column order is important, so define the field names outside cursor definitions
fields = ["Field","Date","Flagged_Field"]
#also putting the index of the flagged field up here, instead of hardcoding
flagindex = 2

# groups is used to store the grouped records for further operations
groups = [] 

# Set search cursor
with arcpy.da.SearchCursor(fc, fields) as cursor:
    # use itertools.groupby to group by Field and then append the results to groups
    for k, g in itertools.groupby(cursor, getGrouper):
        #I do nothing with the key, k, since you only care about the groups, not what they grouped on

# At this point you have your groups
# The rest is to do your example of flagging the most recent date

# map groups to the most recent record in each group
flaggedrecords = map(mostRecentDate, groups)
# update records
with arcpy.da.UpdateCursor(fc, fields) as cursor:
    for row in cursor:
        # Very important to tuple the update row, or else you will not have a match
        if tuple(row) in flaggedrecords:
            # If it is in the flagged records, set the flag
            row[flagindex] = 'Y'
            # Else, unset the flag
            row[flagindex] = ''
  • Thanks @ blord-castillo that worked perfectly and now gives me a good idea as to what direction I need to go in for the rest of my conditional logic. I greatly appreciate your help and the explanations you provided in your code. – standard Sep 10 '15 at 16:46

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.