Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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.

share|improve this question
    
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? –  whuber Aug 11 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. –  whuber Aug 11 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. –  standard Aug 12 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. –  whuber Aug 12 at 20:52

2 Answers 2

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[0] 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[1] = randint(1, dic[row[0]])

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

Edit:

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

share|improve this answer

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.

share|improve this answer
    
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. –  standard Aug 11 at 20:23

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.