I'm trying to dissolve polygons using polygon neighbors in arcgis 10.1, but don't want to use duplicate rows. However, the field values will switch when they're duplicated.
If I run this:
arcpy.env.workspace = "C:\Users\Ant\Documents\ArcGIS\ITN.gdb"
fc = r"BLPUs_PolygonNeighbors"
fields = ["src_OBJECTID","nbr_OBJECTID"]
with arcpy.da.SearchCursor(fc,fields) as cursor:
for row in cursor:
print "{0}, {1}".format(row[0],row[1])
I get:
1, 2
1, 4
2, 1
2, 3
2, 4
3, 2
3, 4
4, 1
4, 2
4, 3
Then when I run my script to dissolve based on these values, I will end up with duplicate polygons such as 1 & 2 as well as 2 & 1. Can someone please help me with writing the UpdateCursor to go through and delete these duplicates? I don't know how to look through when the fields have then switched.
Also, what if I then have three polygons to merge? If I had three columns such as OID1, OID2 and OID3, is there an SQL expression to capture whether the three values in these have been repeated in a different order but in the same row previously? Thanks
2 Answers 2
This should do it with a single pass.
arcpy.env.workspace = r"C:\Users\Ant\Documents\ArcGIS\ITN.gdb"
fc = r"BLPUs_PolygonNeighbors"
fields = ["src_OBJECTID","nbr_OBJECTID"]
row_pairs = set()
with arcpy.da.UpdateCursor(fc,fields) as cursor:
for row in cursor:
row_pair = tuple(sorted(row))
if row_pair in row_pairs:
cursor.deleteRow()
else:
row_pairs.add(row_pair)
-
By creating an empty set, will
row_pair
only be added if it doesn't already exist inrow_pairs
? I'm trying to understand why to use that over creating an empty list.Paul– Paul2013年08月21日 22:49:36 +00:00Commented Aug 21, 2013 at 22:49 -
If the row_pair is not yet in the set, it gets added to the set. But if it's already in the set, the row is a known duplicate and it's deleted. A set is useful because it will only ever have one copy of each value so it won't get excessively big and uses a hash to look up values so searching it is faster than searching a list.Jason Scheirer– Jason Scheirer2013年08月21日 23:30:10 +00:00Commented Aug 21, 2013 at 23:30
-
1thanks, that worked - had to use UpdateCursor, not SearchCursor though. Edited the answer. Cheersuser2581350– user25813502013年08月22日 00:26:45 +00:00Commented Aug 22, 2013 at 0:26
-
+1 Hmm, I need to look more into sets then, thanks!Paul– Paul2013年08月22日 00:53:51 +00:00Commented Aug 22, 2013 at 0:53
-
i guess it was for the deleteRow :)user2581350– user25813502013年08月22日 14:21:29 +00:00Commented Aug 22, 2013 at 14:21
You can use sorted()
(which is a built in Python function) in a generator expression to sort the sub-lists separately and then use sorted()
on the entire list so that it's in ascending order. Using your example:
cursordata = [[1, 2], [1, 4], [2, 1], [2, 3], [2, 4], [3, 2], [3, 4], [4, 1], [4, 2], [4, 3]]
print sorted((sorted(x) for x in cursordata))
[[1, 2], [1, 2], [1, 4], [1, 4], [2, 3], [2, 3], [2, 4], [2, 4], [3, 4], [3, 4]]
This can easily be extended to sublists of length n
.