List unused domain values in a domain via Python

633
6
08-23-2018 08:40 AM
Brian_McLeer
Occasional Contributor II

Any ideas on how to list unused domain values from within a coded domain?

An example is we had PKWY EAST in a domain for street suffixes. I would like to generate a list of domain values that are not being used in a feature class. 

0 Kudos
6 Replies
deleted-user-qpvAI3Fo0MKR
Occasional Contributor III

It's outside the scope of your request, but identifying orphaned domains is out of the box functionality for Laurel Hills GIS GenSentry application.

0 Kudos
forestknutsen1
MVP Regular Contributor

What about comparing all used domain values with a table of all domain values?

deleted-user-qpvAI3Fo0MKR
Occasional Contributor III
0 Kudos
RandyBurton
MVP Regular Contributor

Similar to Forest's approach, I would load the feature's field with the domains you are interested in into a dictionary using code such as:

import arcpy

fc = <your feature>
field = <domain field>

d = {}

with arcpy.da.SearchCursor(fc, (field)) as rows:
    for row in rows:
        if row[0] not in d:
            d[row[0]] = 1
        else:
            d[row[0]] += 1

for k, v in d.iteritems():
    # something like if k not in domainTable ....
    # or if domainTable[value] not in d.keys() ...‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

And then you can compare with the table to domain information.  This would also count the number of rows with specific values.

RandyBurton
MVP Regular Contributor

And in place of TableToDomain/DomainToTable, see ListDomains on how to get a list of domains and coded/max/min values.  You can use something like ListFields to get the domain name a field uses (field.domain).

0 Kudos
RandyBurton
MVP Regular Contributor

Here's a sample script using ideas in my previous posts:

import arcpy

gdb = r"C:\Path\To\file.gdb"
arcpy.env.workspace = gdb # set environment for arcpy

# gdb domains to dictionary # # # # # # #
domDict = {} # empty dictionary
domains = arcpy.da.ListDomains(gdb)
for domain in domains:
    if domain.domainType == 'CodedValue':
        if domain.name not in domDict:
            vList = [] # empty list
            coded_values = domain.codedValues
            for val, desc in coded_values.items():
                vList.append({val:desc})
        domDict[domain.name] = vList
# print domDict

# read feature's fields and domains information # # # # # # #
fc = 'MyFeature' # a feature in the geodatabase
fields = arcpy.ListFields(fc)
fldDict = {} # empty dictionary
for field in fields:
    if len(field.domain):
        fldDict[field.name] = field.domain
# print fldDict

# count values in fields with domains # # # # # # #
domCount = {}
fldList = list(fldDict.keys())
with arcpy.da.SearchCursor(fc, fldList) as rows:
    for row in rows:
        for i, f in enumerate(fldList):
            # print i, fldList, row # index, field name, field value
            if fldList[i] not in domCount:
                domCount[fldList[i]] = {}
            if row[i] not in domCount[fldList[i]]:
                domCount[fldList[i]][row[i]] = 1
            else:
                domCount[fldList[i]][row[i]] += 1
del rows # release any locks
# print domCount

# output the results # # # # # # #
for k, v in domCount.iteritems():
    print "Field: {}".format(k)
    print "  Domain: {}".format(fldDict[k])
    for dLst in domDict[fldDict[k]]:
        for k1, v1 in dLst.iteritems():
            if k1 in v:
                print "    Key:  {} - Description: {} - Count: {}".format(k1, v1, v[k1])
            else:
                print "    Key:  {} - Description: {} - Count: {}".format(k1, v1, 0)

# may need to add code to check for invalid codes in fields ?‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

And my test results:

Field: MyType
  Domain: MyCode
    Key:  1234 - Description: One - Count: 3
    Key:  2345 - Description: Two - Count: 2
    Key:  3456 - Description: Three - Count: 0
    Key:  6789 - Description: Six - Count: 0
    Key:  4567 - Description: Four - Count: 0
    Key:  5678 - Description: Five - Count: 0
    Key:  7890 - Description: Seven - Count: 1
Field: MyColor
  Domain: MyColor
    Key:  Y - Description: Yellow - Count: 1
    Key:  P - Description: Purple - Count: 0
    Key:  B - Description: Blue - Count: 1
    Key:  R - Description: Red - Count: 2
    Key:  G - Description: Green - Count: 2