# Calculate field values using random integer derived from count of like features

I have a feature class which contains features classified by type. What I would like to do in my new field is generate a random number sequence for those like values using a count of the like values. Perhaps the example below better illustrates my question:

``````Field1  Field2
X       random # between 1&4
X       random # between 1&4
X       random # between 1&4
X       random # between 1&4
Y       random # between 1&2
Y       random # between 1&2
Z       random # between 1&3
Z       random # between 1&3
Z       random # between 1&3
``````

I'm thinking I would just use GetCount for the totals and then random.randint(1, GetCount Value) to populate the new field. What I can't seem to figure out is how to have the count reset itself each time it encounters a new value. Thanks for any help you can offer.

• Are the random values supposed to be integers or not? Should they be sampled with or without replacement? Should they be independent? Should they be uniformly distributed within each value of Field1? Aug 11, 2014 at 21:01
• They will necessarily be uniformly distributed based on all the requirements you have provided, because for each value of `Field1` each of the integers from 1 though the number of records with that value will appear exactly once. Note that since they are to be selected without replacement, `randint` will not work. Aug 11, 2014 at 21:22
• @whuber I apologize for my mistake, I am learning and tend to get confused at times, thank you for clearing things up a bit. Aug 12, 2014 at 13:56
• In your followup question you are using `randint`. Should we therefore understand that in the present question you want to sample with replacement? That will generally result in some tied values and gaps among the random values assigned to each instance of `Field1`. Aug 12, 2014 at 20:52

Using the `collections` module, this is quite straightforward:

``````import collections, arcpy
from random import randint

#Given a list, create a dictionary containing the count of each unique item
#sumdict(["x", "x", "x", "x", "y", "y", "z", "z", "z"]) -->
#defaultdict(<type 'int'>, {'y': 2, 'x': 4, 'z': 3})
def sumdict(listvals):
ddict = collections.defaultdict(int)
for val in listvals:
ddict[val]+=1

return ddict

#Read values from Field1 into list and "summarize counts"
dic = sumdict(row for row in arcpy.da.SearchCursor(FC, ("Field1")))

with arcpy.da.UpdateCursor(shp, ("Field1", "Field2")) as cursor:
for row in cursor:
#Grab the value from field1 to set as upper limit for randint()
row = randint(1, dic[row])
``````

This is untested code, but it should get you started.

Edit:

For python > 2.7, `sumdict()` can be replaced with `collections.Counter()`.

I tried this solution and it worked for me in ArcMap:

1. Open attribute table for layer

2. Get summarize for the classification field(here field1) and in step 3 of summarize form,put the name of a table. after summarize finish,the new table will be added to arcmap tables.This table contains 3 fields,ObjectId,field1 and summarization field with name Count_Field1.

3. Join source layer with this table based on Field1,now you have Count_Field1 across you other fields in layer and you can use it in field calculation.

• Thanks for the suggestions, I'm going to look at both methods, I imagine there are a few ways to do this, I was working on a rather cumbersome approach which involved a series of selections, I think either method should get me in the ballpark. Aug 11, 2014 at 20:23