I'm trying to count rows by unique values for a given FeatureClass. I'm using DataStatistics to get the unique values for a specific column for a given FeatureClass.

This seems to be (very) slow with big shapefiles (> 200k of features) - is there a faster way to determine unique values?

The second step of the process (using QueryFilter in combination with FeatureClass.FeatureCount()) seems fast enough although I would be glad if im pointed to a better solution.

public static Dictionary<string, int> CountUniquesStatistic(ITable table, string fldName)
    Dictionary<string, int> uniqueValuesDictionary = new Dictionary<string, int>(StringComparer.CurrentCultureIgnoreCase);

    DataStatistics dataStatistics = new DataStatistics();
    dataStatistics.Field = fldName;
    dataStatistics.Cursor = table.Search(null, false);

    IEnumerator uniqueValues = dataStatistics.UniqueValues;

    while (uniqueValues.MoveNext())
        object current = uniqueValues.Current;
        uniqueValuesDictionary[current.ToString()] = 0;

    foreach (string key in uniqueValuesDictionary.Keys.ToList())
        IQueryFilter queryFilter = new QueryFilter();
        queryFilter.WhereClause = string.Format("{0} = '{1}'", fldName, key);

        uniqueValuesDictionary[key] = table.RowCount(queryFilter);

    return uniqueValuesDictionary;
  • 2
    Related: NIM087476 is bug introduced at 10.1SP1 and is a memory leak for UniqueValues. Feb 25, 2013 at 19:51
  • Do you need to incorporate this into an application? If you want the best performance, why not transfer the data into a database and run a sql group by with count -- super fast even with Access?
    – awesomo
    Feb 26, 2013 at 17:51
  • I have to build an ArcMap Addin and calculate statistics based on selected featureclass columns - waiting 10 seconds for the user is not the end of the world, but not convenient either...
    – Dresel
    Feb 26, 2013 at 18:02

1 Answer 1


I haven't tested this code, but I'd be very interested in how it compares performance-wise with DataStatistics. Maybe use recycling=true when you call Search to for the cursor for datastatistics for a fair comparison. Cast the IFeatureclass to ITable when calling this. I'm also curious how this would compare to python.

public static Dictionary<string, int> CountUniques(ITable table, string fldName)
    int idx = table.Fields.FindField(fldName);
    if(idx == -1)
        throw new Exception(string.Format(
            "field {0} not found in {1}",
    IQueryFilter qf = new QueryFilterClass();

    var outDict = new Dictionary<string,int>(StringComparer.CurrentCultureIgnoreCase);
    ICursor cur = null;
    IRow row = null;
        cur = table.Search(qf, true);
        while ((row = cur.NextRow()) != null)
            string key = row.get_Value(idx) is DBNull ? "<Null>" :
            if (!outDict.ContainsKey(key))
                outDict[key] = outDict[key] + 1;
                outDict.Add(key, 1);
    catch(Exception ex)
        string msg = row == null ? "error getting value" :
            "error getting value for row " + row.OID.ToString();
        throw new Exception(msg, ex);
        if(cur != null)

    return outDict;
  • Sadly it is approximately 4-5 times slower than DataStatistics and FeatureCount combination.
    – Dresel
    Feb 26, 2013 at 17:14
  • @Dresel oh well. I guess that's the cost of more traffic through the interop(?) If it's an issue of blocking the UI, have you considered using a BackgroundWorker ? Feb 26, 2013 at 20:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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