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.
It's outside the scope of your request, but identifying orphaned domains is out of the box functionality for Laurel Hills GIS GenSentry application.
What about comparing all used domain values with a table of all domain values?
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.
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).
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