I am looking for a way which I can search whole my feature class in ArcMap to find if has any NULL
values on it.
I know how can I do this with "Select By Attribute"
, but I am looking for a faster way to do this, like with a Python script.
-
1If you're after a python script what have you got so far? A cursor (arcpy.da) will let you loop through features looking for row[index] == None to find Null values, also look at ListFields resources.arcgis.com/en/help/main/10.2/index.html#//… – Michael Stimson Dec 6 '18 at 22:47
-
I just start to learn python by myself I am good with ArcMap software – Kylie Dec 6 '18 at 22:49
-
3There's little chance a Python script will improve on the performance of a tool like Select By Attribute. Both would be improved by creation of indexes, one per column to be evaluated. – Vince Dec 6 '18 at 22:57
Here's something I quickly put together:
import os, sys, arcpy
InFC = sys.argv[1]
Desc = arcpy.Describe(InFC) # describe the feature class properties
OidName = Desc.OIDFieldName # find out what the OID field is called
AllFields = [Fld.name for Fld in arcpy.ListFields(InFC)] # get a list of field names
FieldRange = range(len(AllFields)) # make a range (a list witn [0,1,2..n] to iterate
OidIndex = AllFields.index(OidName) # the index of the row OID field
with arcpy.da.SearchCursor(InFC) as SCur:
# loop for each row
for SRow in SCur:
# loop for each field
for Idx in FieldRange:
if SRow[Idx] == None:
# if this field, by index, is null issue a warning
arcpy.AddWarning('Row {} has a null value in {}'.format(SRow[OidIndex],AllFields[Idx]))
Start with interrogating the input feature class to get some properties, in this case the name of the OID field and the names of all the fields (ListFields returns field objects, but we just want the names), I'm using a condensed form with iterates the fields an returns a list of field names in a single row which can be a little difficult to understand.
Now open an arcpy.da.SearchCursor on the feature class, by default it will have all fields then iterate the rows and loop by the indices in the range looking for Null (None
) values and issue a warning with the rows OID and the field name that is blank.
To use this script have a read of adding a python script to a toolbox, this tool has only one parameter of type FeatureClass
.
From here you could replace the AddWarning with writing to a file but because you're a beginner I wanted to keep this fairly simple.
-
If there are more than 10k-20k features in a feature class, it's probably worth the performance hit to build an index before doing the query. – Vince Dec 7 '18 at 0:07
If you're after a raw count of null values in any field:
sum(sum(v is None for v in values) for values in arcpy.da.SearchCursor('some_layer', '*'))
If you want to know specifically which rows/fields contain them:
count_nulls = 0
with arcpy.da.SearchCursor('some_layer', '*') as cursor:
for i, row in enumerate(cursor):
null_fields = [name for name, value in
zip(cursor.fields, row) if value is None]
if null_fields:
print 'found nulls in row {}: {}'.format(
i + 1, ', '.join(null_fields))
count_nulls += len(null_fields)
print '{} total null values'.format(count_nulls)
-
I like the condensing to a single row but it's a bit hard for beginners to understand this type of expression. +1 anyway for getting the sum of nulls for a row, that's a great idea. – Michael Stimson Dec 6 '18 at 23:22
-
You can use the da.SearchCursor to check all fields ("*") and stop when the first row with a null value is found:
import arcpy
fc = r'C:\data.gdb\features' #Change
with arcpy.da.SearchCursor(fc,"*") as cursor:
for row in cursor:
if None in row:
print('I found a None')
break