Find matching attributes

795
14
10-03-2017 08:18 AM
2Quiker
Occasional Contributor II

I am trying to update the points selected features field "Verifi2" with "Match" or "No" based on if the 'SiteAddres' field of the selected feature matches the parcels layer 'SiteAddress' field. I currently have the following code but all of the selected features have "No" in the Verifi2 field. Which is not the case because some of the selected point features SiteAddres does match parcels SiteAddress. I would appreciate some help please.

import arcpy 
from datetime import datetime as d
startTime = d.now()

fc1 = "AddresPointsTest" 
fc2 = "TaxParcels1"

#set up cursors
cursor1 = arcpy.da.SearchCursor(fc1, ["SiteAddres", "Verifi2"])  
cursor2 = arcpy.da.SearchCursor(fc2, ["SiteAddress"])


with arcpy.da.UpdateCursor(fc1, ["SiteAddres", "Verifi2"]) as cursor1:  
     for row1 in cursor1:  
          with arcpy.da.SearchCursor(fc2, ["SiteAddress"]) as cursor2:  
               row2 = cursor2.next()  
               #print row2  
               row1[1] = "Match" if row1[0].lower() == row2[0].lower() else "No"  
               #print row1[2]  
               cursor1.updateRow(row1)  

try:
    print '(Elapsed time: ' + str(d.now() - startTime)[:-3] + ')'

except Exception, e:
    # If an error occurred, print line number and error message
    import traceback, sys
    tb = sys.exc_info()[2]
    print "Line %i" % tb.tb_lineno
    print e.message
0 Kudos
14 Replies
MitchHolley1
MVP Regular Contributor

Do these two datasets have a unique ID that links them together?  If so, you could create a dictionary with ID: Address pairs and use that to search the attribute table.  Nested cursors get tricky... 

Just to clarify, are you looking for any Addresses in FC1 that are not in FC2?

0 Kudos
2Quiker
Occasional Contributor II

Yes they do have a unique ID that links them together. I guess i didn't think this through all the way...hummm

So some parcels have an address point (separate layer) but some address points don't match the parcels(separate layer) site addresses i need to find the ones that match and don't match, but only of the selected features in ArcMap.

0 Kudos
MitchHolley1
MVP Regular Contributor

If you make your Python script able to be consumed with ArcMap (via Script Tool), then it will automatically accept a selection.

What you need to do is:
1.) Build a dictionary of ID: Address pairs
2.) Search feature attribute table for presence of Addresses
3.) Update field based on result from 2

This should get you started. 

fc1 = r'complete_path_to_featureClass1'
fc2 = r'complete_path_to_featureClass2'

#build a dictionary of OBJECTID : Address pairs, change OID@ to your uniqueID
addDict = {row[0]:row[1] for row in arcpy.da.SearchCursor(fc1, ['OID@','SiteAddress'])}

#search through fc2 to see if addresses match based on OBJECTID value
#again, change OID@ to your uniqueID
with arcpy.da.UpdateCursor(fc2, ['OID@','SiteAddress','Verifi2']) as cursor:
    for row in cursor:
        if row[0] in addDict:
            if row[1] != addDict[row[0]]: #if the value associated with those ids do not match
                row[2] = 'No'
            else:
                row[2] = 'Match'
            cursor.updateRow(row)
del cursor
2Quiker
Occasional Contributor II

Hi Mitch.

thank you for the reply and help. I tried the code but i am getting the same results as before.

I select the points in Arcmap and run the code in ArcMap python window. All of the point features have 'No' in the Verifi2 filed.

on line 12 of your code should it be if row[1] != addDict[row[1]] since your comparing the SiteAddress and SiteAddres fields?

Here is the code i am working with.

import arcpy 
from datetime import datetime as d
startTime = d.now()

fc1 = "AddresPointsTest" 
fc2 = "TaxParcels1"

#set up cursors
cursor1 = arcpy.da.SearchCursor(fc1, ["SiteAddres", "Verifi2"])  
cursor2 = arcpy.da.SearchCursor(fc2, ["SiteAddress"])

#build a dictionary of OBJECTID : Address pairs, change OID@ to your uniqueID
#addDict is for the taxparcels
addDict = {row[0]:row[1] for row in arcpy.da.SearchCursor(fc2, ['OID@','SiteAddress'])}

#search through fc2 to see if addresses match based on OBJECTID value
#again, change OID@ to your uniqueID
#UpdateCursor is for the address points
with arcpy.da.UpdateCursor(fc1, ['OID@','SiteAddres','Verifi2']) as cursor:
    for row in cursor:
        if row[0] in addDict:
            if row[1] != addDict[row[0]]: #if the value associated with those ids do not match
                row[2] = 'No'
            else:
                row[2] = 'Match'
            cursor.updateRow(row)
del cursor

try:
    print '(Elapsed time: ' + str(d.now() - startTime)[:-3] + ')'

except Exception, e:
    # If an error occurred, print line number and error message
    import traceback, sys
    tb = sys.exc_info()[2]
    print "Line %i" % tb.tb_lineno
    print e.message

0 Kudos
MitchHolley1
MVP Regular Contributor

A couple things... do not run this code in the Python executable window inside of ArcMap.  Please make this tool a Script Tool.  It will be much easier to manage and deploy. Secondly, no... the addDict[row[0]] is correct because you're asking Python to compare the value of the dictionary associated with that ID.  Please research dictionaries and script tools.  You may want to print the keys and values of the dictionary to make sure it's built properly. 

0 Kudos
2Quiker
Occasional Contributor II

I tried your suggestion to put it into a script but i still just get "No" for all the features.

Would it have to do with the fact that the taxparcels address filed are all upper case letters and the points address field are all lower case?

0 Kudos
MitchHolley1
MVP Regular Contributor

Yes... the != operation is a strict comparison.  I would include .strip() and .lower() for comparison. 

0 Kudos
2Quiker
Occasional Contributor II

tired the following but i get following error:

if row[1].strip().lower() != addDict[row[0].strip().lower()]: #if the value associated with those ids do not match
AttributeError: 'int' object has no attribute 'strip'

if row[1].lower() != addDict[row[0].lower()]:

&

if row[1].strip().lower() != addDict[row[0].strip().lower()]:

0 Kudos
MitchHolley1
MVP Regular Contributor

if row[1].strip().lower() != addDict[row[0]].strip().lower()

0 Kudos