How to remove a specific unique value with arcpy

5945
14
05-11-2015 02:48 AM
Yaron_YosefCohen
Occasional Contributor II

Hi everyone

For disclosure, i asked this question in python - How to remove a specific unique value with arcpy - Geographic Information Systems Stack Exc... but didn't get useful answers.

using arcpy, i would like to remove from 50 mxd files, a specific unique value called "residence a" (exist in 3 layers) from the table of content.

enter image description here

The value of "residence a" is the number  "70"  in the attribute table (in field named "YEUD")

enter image description here

When i use this code:

import arcpy,os,sys
from arcpy import env

env.workspace = r"C:\Project"
for mxdname in arcpy.ListFiles("*.mxd"):
    mxd = arcpy.mapping.MapDocument(r"C:\Project\\" + mxdname)
    df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]
    lyr = arcpy.mapping.ListLayers(mxd, "*")[0]
    if lyr.symbologyType == "UNIQUE_VALUES":
        vals = lyr.symbology.classLabels
        for v in vals:
            if v == "residence a":
                print mxdname
                print lyr.name
                print ("1 in layer " + lyr.name)
                arcpy.mapping.RemoveLayer(df, v)        
    mxd.save()
del mxd

i get en error:

>>> Project -.mxd mig1 1 in layer mig1  Traceback (most recent call last): File "C:/Users/yaron.KAYAMOT/Desktop/remove UNIQUE_VALUES in lyr.py", line 18, in    <module> arcpy.mapping.RemoveLayer(df, v) File "C:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy\arcpy\utils.py", line 182, in fn_ return fn(*args, **kw) File "C:\Program Files (x86)\ArcGIS\Desktop10.3\ArcPy\arcpy\mapping.py", line 1845,     in RemoveLayer assert isinstance(remove_layer, Layer) AssertionError >>> 

I search desperately a solution to my problem -thanks

0 Kudos
14 Replies
DanPatterson_Retired
MVP Emeritus

the assertion error suggests that it is of the wrong type.  The way you have it set up 'v' is a class in classlabels.  You want to remove the layer apparently which I think is 'lyr' so I suspect if you want to remove the layer if it contains that label, then you should be using  arcpy.mapping.RemoveLayer(df, lyr) .  

Yaron_YosefCohen
Occasional Contributor II

but i don't want to remove layers mig 1 2 3 .i want to remove only value "residence a",so my TOC will be:

1.jpg

0 Kudos
JakeSkinner
Esri Esteemed Contributor

Hi Y.Y.C,

You can append the unique values to a list, remove the value you do not want to use, and then update the symbology.  Below is an example that removes the value 'Philadelphia International Airport' from a unique value list, and then updates the symbology.  Also, here is a helpful link.

import arcpy
mxd = arcpy.mapping.MapDocument("current")
lyr = arcpy.mapping.ListLayers(mxd, "Airports")[0]
airportList = []
rows = arcpy.da.SearchCursor(lyr, ["NAME"])
for row in rows:
  airportList.append(row[0])

#remove duplicates from list
airportList = dict.fromkeys(airportList)
airportList = airportList.keys()

#remove unique value
airportList.remove('Philadelphia International Airport')

#update symbology
if lyr.symbologyType == "UNIQUE_VALUES":
  lyr.symbology.classValues = airportList
  lyr.symbology.showOtherValues = False

arcpy.RefreshActiveView()
arcpy.RefreshTOC()
del mxd
Yaron_YosefCohen
Occasional Contributor II

Hi Jake,

in your code you work only with one layer. I want that arcpy will iterate all layers in all 50 mxd's. i have many other layers in the mxd's with different names that including value "residence a" in them.

To your opinion, i must change the layer name every time i want to work on specific layer- this will take a  lot of time

0 Kudos
JakeSkinner
Esri Esteemed Contributor

You would just need to add a 'for' loop for the layers within your MXD.  Ex:

import arcpy  
mxd = arcpy.mapping.MapDocument("current")  
lyrs = arcpy.mapping.ListLayers(mxd, "*")
for layer in lyrs:
  airportList = []  
  rows = arcpy.da.SearchCursor(layer, ["NAME"])  
  for row in rows:  
    airportList.append(row[0])  
    
  #remove duplicates from list  
  airportList = dict.fromkeys(airportList)  
  airportList = airportList.keys()  
    
  #remove unique value  
  airportList.remove('Philadelphia International Airport')  
    
  #update symbology  
  if layer.symbologyType == "UNIQUE_VALUES":  
    layer.symbology.classValues = airportList  
    layer.symbology.showOtherValues = False  
  
arcpy.RefreshActiveView()  
arcpy.RefreshTOC()  
del mxd 
Yaron_YosefCohen
Occasional Contributor II

Hi Jake,

I tried to build this code (i  also created shp called "Airports" with field "NAME" 😞

import arcpy,os,sys  
from arcpy import env  
  
env.workspace = r"C:\Project\gis"  
for mxdname in arcpy.ListFiles("*.mxd"):  
    mxd = arcpy.mapping.MapDocument(r"C:\Project\gis\\" + mxdname)  
    df = arcpy.mapping.ListDataFrames(mxd, "Layers")[0]  
    lyrs = arcpy.mapping.ListLayers(mxd, "*") 
    for layer in lyrs:
        airportList = []    
        rows = arcpy.da.SearchCursor(layer, ["NAME"])    
        for row in rows:
            airportList.append(row[0])     
        #remove duplicates from list    
        airportList = dict.fromkeys(airportList)    
        airportList = airportList.keys()    
      
        #remove unique value    
        airportList.remove('Philadelphia International Airport')    
      
        #update symbology    
        if layer.symbologyType == "UNIQUE_VALUES":
            layer.symbology.classValues = airportList    
            layer.symbology.showOtherValues = False 

    mxd.save()  
del mxd

but get an error:

>>> ================================ RESTART ================================
=
>>> 


Traceback (most recent call last):
  File "C:\Users\yaron.KAYAMOT\Desktop\python.py", line 19, in <module>
    airportList.remove('Philadelphia International Airport')
ValueError: list.remove(x): x not in list
>>> 
0 Kudos
DanPatterson_Retired
MVP Emeritus

​it isn't in the list...or is spelled differently always test for existence and return an error warning

to_remove = 'some airport'

if to_remove in airportList:

    airportList.remove(to_remove)

else:

    print "not there bud..."

Yaron_YosefCohen
Occasional Contributor II

How can i remove 2 unique values?

0 Kudos
DanPatterson_Retired
MVP Emeritus

removing multiple values from lists gets tricky since the position of values in a list changes as the list gets smaller and smaller.  It is better to regenerate what you want from what you have and don't want.

A small example...and one of many, many, many options is as follows.

  • load, compile and run the script below
  • change the data and omit variables to experiment
  • implement on your own data and data structure

def remove_vals(data,omit):
    as_set = set(data)
    out_lst = [ x for x in data if x not in omit]
    return out_lst

if __name__=="__main__":
    """change below to suit"""
    data = ["a", "d","e","b","c","a","a","a","b","a","c"]
    omit = ["a","e"]
    returned = remove_vals(data,omit)
    frmt = "\nInputs...{}\nTo remove...{}\nOutputs...{}"
    print(frmt.format(data,omit,returned))

The results from the above run are as follows.

>>>
Inputs...['a', 'd', 'e', 'b', 'c', 'a', 'a', 'a', 'b', 'a', 'c']
To remove...['a', 'e']
Outputs...['d', 'b', 'c', 'b', 'c']

Now don't try to copy this code exactly on your problem...emulate and consider what you have, what you want, then go for a solution