9

I have a number of columns in a number of tables withinh a FGDB where I need to extract the unique values for each column.

For Example: the values may be [1,2,2,2,3,4], and I am trying to return [1,2,3,4]

I could do this job a number of other ways in ARCGIS but I am trying to extend myself.

I have found a piece of python on the web that I think will do the job but I am struggling to get it to run (I keep getting an invalid syntax error as I keep getting the syntax error in line 3) this will no doubt be a really simple user error.

Code Snippet below

import arcpy

def unique_values(r'N:\GISProjects\Landuse\Plant_Biosecurity_Project\ArcGIS_Online.gdb\Holdings_Property_Merge' , 'LU_ALUMMaj'):
with arcpy.da.SearchCursor(table, [field]) as cursor:
    return sorted({row[0] for row in cursor})

This is the Error Message I get from sublime text:

 File "C:\Users\hawkinle\Desktop\STDTAS\Unique_Data.py", line 3
def unique_values(r'N:\GISProjects\Steve_Eastwood_Landuse\Plant_Biosecurity_Project\ArcGIS_Online.gdb\Holdings_Property_Merge' , 'LU_ALUMMaj'):
                                                                                                                             ^
SyntaxError: invalid syntax
[Finished in 0.1s with exit code 1]

Updates from Original Question

I have now updated my code with the answer provided by below but am recieving a secondary error.

New Code Snippet:

import arcpy

def unique_values(table , field):
    with arcpy.da.SearchCursor(table, [field]) as cursor:
        return sorted({row[0] for row in cursor})

myValues = unique_values(r'N:\\GISProjects\\Landuse\\Plant_Biosecurity_Project\\ArcGIS_Online.gdb\\Holdings_Property_Merge' , 'LU_ALUMMaj')

print (myValues)

I am getting a new error message related to a runtime error

Traceback (most recent call last):
File "C:\Users\hawkinle\Desktop\STDTAS\Unique_Data.py", line 7, in <module>
myValues = unique_values(r'N:\\GISProjects\\Steve_Eastwood_Landuse \Plant_Biosecurity_Project\\ArcGIS_Online.gdb\\Holdings_Property_Merge' , 'LU_ALUMMaj')
 File "C:\Users\hawkinle\Desktop\STDTAS\Unique_Data.py", line 4, in unique_values
with arcpy.da.SearchCursor(table, [field]) as cursor:
RuntimeError: cannot open 'N:\\GISProjects\\Steve_Eastwood_Landuse\\Plant_Biosecurity_Project\\ArcGIS_Online.gdb\\Holdings_Property_Merge'

[Finished in 8.0s with exit code 1]

I assume from the reading I have done that this relates to setting the env.workspace ?

Just showing Proof that it exisist

  • 1
    please edit your question to include your entire error message (as text) – Midavalo Aug 25 '16 at 23:59
  • Your new error shouldn't have anythign to do with the env.workspace I don't think. Try either taking off the r before the path, or changing the \` to ` in the path (and leave the r there). Does that Geodatabase exist? – Midavalo Aug 26 '16 at 1:06
  • Are you trying to isolate all of the unique values in a field? For example, say you have the following values [1,2,2,2,3,4], are you trying to return [1,2,3,4]. Please update the post to include this information. – Aaron Aug 26 '16 at 1:13
  • @Midavalo did you meant changing the path tolook like this ?r'N: GISProjects _Landuse Plant_Biosecurity_Project ArcGIS_Online.gdb Holdings_Property_Merge' , 'LU_ALUMMaj' – Leith Hawkins Aug 26 '16 at 1:18
  • 1
    Thanks - fruther proof that im not very smart but I can lift heavy things. I owe you a speights!! – Leith Hawkins Aug 26 '16 at 2:08
13

You've pretty much got it, you just need to specify the name of your parameters table and field in your function definition, and then pass those values when you call the function. Also watch your indentation, as it's vital for Python.

def unique_values(table , field):
    with arcpy.da.SearchCursor(table, [field]) as cursor:
        return sorted({row[0] for row in cursor})

myValues = unique_values(r'N:\GISProjects\Landuse\Plant_Biosecurity_Project\ArcGIS_Online.gdb\Holdings_Property_Merge' , 'LU_ALUMMaj')

print (myValues)

Basically this is saying that when you call the function unique_values() you'll pass values to two parameters, one called table, the other called field. These are then used in your function. When you call the function, in the line

myValues = unique_values(r'N:\GISProjects\Landuse\Plant_Biosecurity_Project\ArcGIS_Online.gdb\Holdings_Property_Merge' , 'LU_ALUMMaj')  

you are passing the values to these parameters.

This is the same as declaring your parameters separately and passing them to the cursor directly:

table = r'N:\GISProjects\Landuse\Plant_Biosecurity_Project\ArcGIS_Online.gdb\Holdings_Property_Merge'
field = 'LU_ALUMMaj'

with arcpy.da.SearchCursor(table, [field]) as cursor:
    myValues = sorted({row[0] for row in cursor})

print myValues
  • ahh that makes sense , when you include the individual paramters below I get what you are saying thankyou! . I am know moving up the chain of errors as I am getting a run time error which isnt allowing me to open the existing database. Ill update my question. – Leith Hawkins Aug 26 '16 at 0:43
  • Why does the sorted () line return just one unique instance of each value when the sorted() function returns duplicates if you run it on a simple list like ['a', 'b', 'a', 'b']? I have been using this reply for some time and realized I did not understand why it works. – Dylan Warburg Jan 29 at 19:49
  • 2
    @DylanWarburg Because you're not passing a list of values, you are passing a set. If you add your list items above to a set, eg set(['a', 'b', 'a', 'b']), it will return unique values {'a', 'b'}. Using sorted() just returns them in sorted order as a simple set is unsorted. – Midavalo Jan 30 at 3:10
  • If the field you are looking for unique values from is not a string, you should add: return sorted({str(row[0]) for row in cursor}) – MKelly Jun 6 at 15:55
5

I would advise using Python's built-in set() function along with a SearchCursor as a generator expression to find the unique values. You'll find this approach extremely efficient with large or small datasets:

import arcpy

fc = r'C:\path\to\your.gdb\featureclass'

unique_values = set(row[0] for row in arcpy.da.SearchCursor(fc, "some_field"))
  • 1
    This is essentially what @Midavalo's answer is doing as well as the {} braces are being used to define a set object. – user2856 Aug 26 '16 at 4:18
  • 1
    I considered suggesting the exact same thing. If what you want is a list you can always turn the set back into a list with the native python list() fx. – jbchurchill Aug 27 '16 at 1:06
3

The following approach was published on https://arcpy.wordpress.com/2012/02/01/create-a-list-of-unique-field-values/ It is using arcpy and numpy and has a smaller memory footprint than the SearchCursor approach.

import arcpy
import numpy

def unique_values(table , field):
    data = arcpy.da.TableToNumPyArray(table, [field])
    return numpy.unique(data[field]).tolist()

myValues = unique_values(r'N:\GISProjects\Landuse\Plant_Biosecurity_Project\ArcGIS_Online.gdb\Holdings_Property_Merge' , 'LU_ALUMMaj')

print (myValues)
0

I know it's an old question, but I'll leave this here for anyone who stumbles across this looking for help. Using arcpy.Frequency_analysis() quickly puts all the unique values from a field into a new table, which you can then use for cursor operations. One single command to do what all these other solutions do and faster and easier. As a bonus, you also get a count of how many times each value appears.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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