Wednesday 26 April 2017

arcpy - Iterative position within Field Calculator/Python


I'm not great with Python or programming in general, so I'm not even sure how to ask this question.


Basically what I've got is in the left column, and what I want is in the right column.


UniqueID    POSITION
a 1
a 2
a 3

a 4
a 5
b 1
c 1
c 2
d 1
e 1

I guess what I need to do is loop through the sorted UniqueID field and increment the Position field UNTIL the UniqueID changes, in which case the Position should reset to 1.


NFI how to make this actually work. I've done a lot of searching and have found some promising-looking code, but I just don't have the know-how to make it fit my problem. Sorry about my brain. My script right now looks like "Baby's first adventures with arcpy," and since this is slightly more complicated than a simple arcpy call, it's stopped me in my tracks.



I guess I'm looking for something that works as part of a CalculateField operation?



Answer



Cursors are your friend. You want to use the update cursor. The documentation explains it pretty well, but essentially, the cursor returns a set of rows that you can loop through. The update cursor allows you to edit the data. You can also sort your result.


I can think of three very simple approaches all of which will do what you want:



  1. As you suggest

  2. Make a list of the UniqueID values (e.g. uniqueID_list = ['a', 'b', 'c', 'd']) and loop over this list using the current value in the where_clause of the cursor to preselect a given 'UniqueID' and then iterate the returned rows in a nested loop. This is a good approach if the position value is dependent on some other attribute because you can use the 'sort' clause of the currsor.

  3. Make an empty dictionary (uniqe_dict = {}). Get all rows using an update cursor and start looping over them. For each row test the value of uniqueId against the dictionary. If it exists in the dictionary, add one to the dictionary value. If the uniqueId is not in the dictionary add it as a new key to your dictionary with a value of 1. Now update the 'position' field with the dictionary value of the current uniqueId key.


Any of these approaches will work. The 3rd one sounds more complicated than it is but does not reuire that you find out what all your uniqueIds are beforehand and saves the nested loops of approach #2 (if some other order is important you can still pre-sort on the third field beforehand).



There is a fourth approach that requires no coding at all and will work if you are only interested in the relative order and not the actual value of your position field. That is to look up the FID value for any of uniqueId.


No comments:

Post a Comment

arcpy - Changing output name when exporting data driven pages to JPG?

Is there a way to save the output JPG, changing the output file name to the page name, instead of page number? I mean changing the script fo...