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.

Is it possible to use arcpy.da.SearchCursor() to get a count of unique features in a field without a dictionary?

So, by this I mean if I have a field called TEXT which contains 10,000 rows populated with either A or B. Can I use the da.SearchCursor to quickly give me the count for the total amount of A in TEXT and B in the TEXT?

I know it is possible to use Summary Statistics or the Get Count tool but these involve having to make a feature layer and then selecting features or kicking out a table. I looking to have a few steps as possible in my script :-)

share|improve this question
    
I know you state that you can use the Summary Statistics tool but you don't want to because it involves creating a new table but have you tried using the IN_MEMORY workspace? This is like a simple geodatabase held in RAM so when the script finishes or you shut down ArcMap it's all gone, no temporary data clogging up your hard drive. Worth the investigation? –  Hornbydd Aug 8 at 13:54
    
@Hornbydd it's faster to do the calculations in Python directly and store the results in a dict/list/whatever, rather than creating a table and then having to use a SearchCursor on that to get your results. –  nmpeterson Aug 8 at 14:04
1  
Out of curiosity, why the specific request to do this "without a dictionary"? Dicts are great! –  nmpeterson Aug 8 at 14:36
    
Mainly because its a small tally that's needed as part of a bigger script. I have used dict's in the script, to effectively pivot tables from a CSV file into a FC table, but I'm looking for a very quick and fast running solution to tallying how many of two values are found in on field that appear later in the script. –  spk578 Aug 8 at 14:53

3 Answers 3

up vote 6 down vote accepted

Use collections.Counter:

import collections

with arcpy.da.SearchCursor(feature_class, field) as cur:
    count_of_items = collections.Counter(row[0] for row in cur)

print "Sorted items"
print "----"

for item in sorted(count_of_items.items(), key=lambda x:x[1]):
    print "{0:>12} {1:>4}".format(item[0], item[1])
share|improve this answer
1  
+1 for collections. –  Paul Aug 8 at 14:23
    
I got up early and now I'm being slow...how do you access the count values being produced? I can print them off on the console but I'm looking to assign, in this case, the count values (number only) to variables so I can utilize them later in my script. Any help is appreciated whilst I go find some coffee :-) –  spk578 Aug 11 at 10:33
    
I've got it now... with arcpy.da.SearchCursor(fc, field) as cur: count_of_items = collections.Counter(row[0] for row in cur) CountA = count_of_items.items()[0][1] CountB = count_of_items.items()[1][1] for item in sorted(count_of_items.items()): print CountA print CountB –  spk578 Aug 11 at 11:45

I think this is the easiest way to do it:

all_values = [r[0] for r in arcpy.da.SearchCursor(table, [field])]
unique_values = set(all_values)
count_dict = {}
for value in unique_values:
    count_dict[value] = all_items.count(value)
share|improve this answer
2  
This keeps the entire result set in memory unnecessarily. If you just iterate over the cursor and populate the dictionary as you go, you'll avoid having to keep that all in memory. –  Jason Scheirer Aug 8 at 14:23

Well if you really want to use a cursor to perform this task, don't want a dictionary, and it's only a couple of known/expected values, you could just loop through each record in the search cursor's resulting dataset and do something like (pseudo code below, adjust to work for your situation and syntax requirements).

aCounter = 0
bCounter = 0
for record in cursorOutput:
    if record[field] == "String A":
        aCounter += 1
    elif record[field] == "String B":
        bCounter += 1

But you can also just use summary statistics GP tool and write the output to a scratch workspace environment and not keep the output, thus possibly mitigating some of your concerns with using that method.

Just a couple of thoughts, hope it helps.

share|improve this answer
    
This code requires you to have a pre-calculated list of every value that could happen in the cursor, though. –  Jason Scheirer Aug 8 at 14:22

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.