0

I try to use this python code in order to delete duplicated feature which as the same xy coordinate of centroid (i created those fields with Calculated Geometry in the attribute table):

import arcpy
'''
first we create x center coordinate field (the same for y) in the attribute
table manually, then we will run this code.
'''
list1 = []
listToDeleteX = []
listToDeleteY = []
fc = r"G:\desktop\Project\lyr\polygon.shp"
# check the x coordinate
with arcpy.da.UpdateCursor(fc, "xCenter") as cursor:
    for row in cursor:
        list1.append(row)
        if list1.count(row)>1:
            listToDeleteX.append(row)

 # check the y coordinate
with arcpy.da.UpdateCursor(fc, "yCenter") as cursor:
    for row in cursor:
        list1.append(row)
        if list1.count(row)>1:
            listToDeleteY.append(row)

listToDeleteY.append(listToDeleteX)

in the end of the code i added the x list to the y list but i don't know how to delete the duplicated rows.

I work with arcGIS for Desktop so i don't have any extensions and i can't use the "arcpy.DeleteIdentical_management" tool.

This is the attribute table of the polygon layer:

enter image description here

  • 1
    It is much easier done with the dictionary. Start populating it with first cursor using xy tuple as a key and fid a s value. If key not in dictionary, add it, otherwise populate list of fids to delete. Use select query fid in () and delete features tool to accomplish the task – FelixIP Sep 5 '16 at 9:43
  • how to do it with a dictionary? – newGIS Sep 5 '16 at 10:01
  • 1
    Rather than use a dictionary why not use a Set? When you add to a set, if the value exists already then it's dropped, so you build up a unique list of values. – Hornbydd Sep 5 '16 at 10:27
  • how to integrated it in my code? – newGIS Sep 5 '16 at 10:48
  • I found Sets are good for creating unique number lists but in hind sight I think @FelixIP idea of using a dictionary is a better way to go as then you need only traverse the table once. – Hornbydd Sep 5 '16 at 11:43
4

This code will work on a table and searches a numeric field called test to find and delete duplicates. It assumes the first instance of a duplicate value is the one you want to keep.

import arcpy

def main():
    dict = {} # dictionary, key is test value, item is objectID
    tbl = r"C:\Scratch\fGDB_AIS_Cleaned.gdb\test" # Table to test

    # Search table adding only the first occurance of a value and it's objectID
    print "reading dataset..."
    with arcpy.da.SearchCursor(tbl,["OBJECTID","test"]) as cursor:
        for row in cursor:
            objID = row[0]
            val = row[1]
            if dict.has_key(val) == False:
                dict[val] = objID

    # Get a list of objectIDs to keep
    oList = dict.values()

    # Check duplicates if they exist
    n = int(arcpy.GetCount_management(tbl).getOutput(0))
    if n > len(oList):
        print "deleting duplicates..."
        # create a sql expression on ObjectID
        sql = "OBJECTID NOT IN (" + str(oList) + ")"
        sql = sql.replace("[","")
        sql = sql.replace("]","")

        # Delete duplicates
        arcpy.MakeTableView_management(tbl,"tocleanup")
        arcpy.SelectLayerByAttribute_management("tocleanup","NEW_SELECTION",sql)
        arcpy.DeleteRows_management("tocleanup")
        print "deleted duplicate rows!"
        arcpy.Delete_management("tocleanup")

if __name__ == '__main__':
    main()
    print "finished!"

One thing to consider, I have found deleting from very large datasets (e.g. millions of rows) can be very slow. It is much quicker to copy out rows you want to keep into a new dataset.

| improve this answer | |
  • i don't understand where to insert the key\ value of the dictionary? – newGIS Sep 5 '16 at 12:56
  • The insertion is this line: dict[val] = objID. Unlike VB which would have been something like myDict.Add(val,objID) you simply assign it to insert it. – Hornbydd Sep 5 '16 at 13:19
  • sorry but i don't understand: i want to use the xCenter and the yCenter fields as the key\value- where i insert them? – newGIS Sep 5 '16 at 13:28
  • 1
    +1 str(tuple(oList)) will make it shorter – FelixIP Sep 5 '16 at 18:33
  • 1
    @Hornbydd, don't forget yourTuple+=(-1,) because this thing fails with single entry – FelixIP Sep 5 '16 at 22:44

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.