Hello,
I'm trying to create a function that leverages the auto increment function which is provided as a field calculator example in ArcGIS Pro's Calculate Field Python examples. The auto increment function is pretty straight-forward however, I'm looking to increment based on the attributes of another field. I've attached an example of the desired output. Below I've provided a snippet of the code where I've attempted to create a function that does what I've described but it doesn't seem to be working and I'm probably missing some important information about how field calculator works with tables. In the autoincrement function, you set the initial value to 0. But in an attempt to keep my function generic, I want to set the initial value to whatever is passed in when the function is called, then keep comparing.
new = ''
def autoIncrementbyAttr(attribute):
global new
exist = attribute
if (exist == new):
return autoIncrement()
else:
new = attribute
rec=0
rec=0
def autoIncrement():
global rec
pStart = 1 #adjust start value, if req'd
pInterval = 1 #adjust interval value, if req'd
if (rec == 0):
rec = pStart
else:
rec = rec + pInterval
return rec
This type of problem, where you need to keep track of key/value pairs (county/map #), is best organized in a dictionary, where for each key (county) you increment the value (map #). See: 5. Data Structures — Python 2.7.15 documentation
Here's an example, not using the field calculator (sorry). In the field calculator, counter_dict should be global, and instead of appending to output_list, you'd return the value counter_dict[county]:
county_list =
['Marin',
'Napa',
'Napa',
'Marin',
'Marin',
'Napa',
'Marin',
'Marin',
'Napa',
'Napa',
'Napa',
'Napa',
'Marin',
'Napa',
'Marin',
'Napa',
'Marin',
'Marin',
'Napa',
'Marin']
counter_dict = {}
output_list = []
for county in county_list:
counter_dict[county] = counter_dict.get(county, 0) + 1
output_list.append([county, counter_dict[county]])
output_list =
[['Marin', 1],
['Napa', 1],
['Napa', 2],
['Marin', 2],
['Marin', 3],
['Napa', 3],
['Marin', 4],
['Marin', 5],
['Napa', 4],
['Napa', 5],
['Napa', 6],
['Napa', 7],
['Marin', 6],
['Napa', 8],
['Marin', 7],
['Napa', 9],
['Marin', 8],
['Marin', 9],
['Napa', 10],
['Marin', 10]]
You can use the following field calculator expression.
A demo using a list is given in the example and a screen shot of it in an actual field calculation is given
d = ['a', 'b', 'a', 'a', 'c', 'd', 'b', 'a', 'b', 'd']
"""
Count the number of 'val's that exist in a field and number and format
them, incrementing the number each time one is found
"""
kv = {} # empty dictionary
cnt = 0
def key_count(val):
global kv
#global cnt
if val not in kv.keys():
cnt = 0
kv[val] = 0
ret = "{}_{:03.0f}".format(val, cnt)
else:
cnt = kv[val] + 1
kv[val] = cnt
ret = "{}_{:03.0f}".format(val, cnt)
return ret
for i in d:
print(key_count(i))
a_000
b_000
a_001
a_002
c_000
d_000
b_001
a_003
b_002
d_001
Attached is the field calculator expression that you can load *.cal file
It was tested in ArcGIS Pro, but hopefully should work in a python 2.7 environment
Of course... you will have to modify to suit your needs.. and if you have fewer than 1000's of records, then you can easily change the padding format from
ret = "{}_{:03.0f}".format(val, cnt) # padding for 1000's of records duplicate
ret = "{}_{:02.0f}".format(val, cnt) # padding for 100's
ret = "{}_{:01.0f}".format(val, cnt) # padding for a few.... get the drift???
Functionality added to Table Tools for PRO should you move forward with Pro.
The functionality is essentially the same, but use numpy to vectorize the calculations.