Select to view content in your preferred language

Query for orginal numbers

2268
26
09-23-2019 03:48 PM
CCWeedcontrol
Frequent Contributor

I am trying to query a filed to find original parcels, i would like to create a filled and mark the ones that are original and don't have not split. Currently the field is a string with a length of 11. Some parcels have 5, some 8 and some 10 - not including the alph letter. Hopefully i have explained good what I am needing, i am just not sure how to do this. At first i thought of doing unique numbers but some how it would need to know if the first 5 digits are used, there are some duplicate numbers as well. I am kind of lost on how to proceed, if anyone has done something similar could share some code please?

the attributes are as follows for example;

R00062 (Original parcel)--> has R00062010 (Split parcel, next one below) - this is not one i need marked.

R00062010 - Not Original parcel

R32073114 - Not Original parcel 

R32078 - Original parcel because there is no other parcel number associated with it, need this one mark in the new filed.

R32079 - Original parcel because there is no other parcel number associated with it,, need this one mark in the new filed.

R32081 - Original parcel because there is no other parcel number associated with it,, need this one mark in the new filed.

R32082012 - Not Original parcel 

R32083012 - Not Original parcel 

0 Kudos
26 Replies
DanPatterson_Retired
MVP Emeritus

row[2] would mean that you have 3 elements in the field since python is 0-based, row[1] would be the second element... row[0], the first

RandyBurton
MVP Alum

I like Joshua Bixby ‌'s code as it is simple.  When you are in the UpdateCursor, just use the first 6 characters of the parcel id to check if it is in the original list, then set the flag. Here is that approach for you to test.

import arcpy
from collections import Counter

tbl = r'C:/Temp/ParcelNumberSample2.dbf'

# read parcel id into counter
parcel_count = Counter(
    (pid[:6] for pid, in arcpy.da.SearchCursor(tbl,"PARCEL_NO"))
)

original = [] # an empty list for original parcels

for pid,cnt in parcel_count.items():
    if cnt == 1: # origional parcels will only have a count of 1
        original.append(pid)

# print original

with arcpy.da.UpdateCursor(tbl,["PARCEL_NO","Org_Par"]) as cursor:
    for row in cursor:
        if row[0][:6] in original: # trim row[0] to 6 characters and check if in original list
            # print row[0]
            row[1] = 'Orig'
            # cursor.updateRow(row) # you can just update the flagged records by uncommenting this line and deleting the remaining lines
        else: # or add an else to set non-original fields to a value
            row[1] = 'N'
        cursor.updateRow(row)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

If you find that you do need the object id to do some other things, here's and updated version of my code that may give you some ideas.  I used where OBJECTID IN ( nnn, nnn) in my SQL; you may need to make adjustments for your version.  I was also testing with a file geodatabase where you might be testing with a shapefile.

import arcpy

tbl = r'C:/Temp/ParcelNumberSample2.dbf' # use your table name

# read oid and parcel_id into dictionary
parcels = [[r[0],r[1]] for r in arcpy.da.SearchCursor(tbl, ['PARCEL_NO', 'OBJECTID'])] # use your field names

# print parcels

# empty dictionaries for parents and children
parentFound = {} # format: { parent parcel id : object id }
childFound = {} # format: { parent parcel id : ( object id, count of items) }

for p in parcels:
    parent = p[0][:6]
    # print parent
    if len(p[0]) > len(parent):
        if parent in childFound.keys():
            childFound[parent] = (p[1], 1 + childFound[parent][1] )# this will be last child found (by objectid)
        else:
            childFound[parent] = (p[1], 0)
    else:
        parentFound[parent] = p[1] # this will be last parent found (by objectid)

# print parentFound
# print childFound

objID = [] # empty list for object ids

for k in parentFound.keys():
    if k not in childFound.keys(): 
        # print k, parentFound, "parent is orig"  # this is the parcelid and objectid of parent parcels, add to a list
        objID.append(parentFound)

for k in childFound.keys():
    if k not in parentFound.keys():
        if childFound[1] < 1:
            # print k, childFound[0], "child is orig" # this would be the parent parcelid that was NOT found, add to the list also
            objID.append(childFound[0])

# print sorted(objID)
where = "OBJECTID IN ({})".format(str(sorted(objID)).strip('[]')) # substitute name of object id field

with arcpy.da.UpdateCursor(tbl,["OBJECTID","Org_Par"], where_clause=where) as cursor:
    for row in cursor: # this will just update the rows where an original parcel id was found
        print row
        row[1] = 'Orig'
        cursor.updateRow(row)‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
CCWeedcontrol
Frequent Contributor

Excellent thank you!

0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Based on your requirements, and the possibility of duplicate parcel IDs, the following will generate a Python set of parcel IDs that meet your conditions.  You can then use an update cursor to loop over the records and check whether the ID is in the set, and then flag the record accordingly.

>>> import arcpy
>>> from collections import defaultdict
>>> 
>>> tbl = # path to table containing "PARCEL_NO" field
>>> 
>>> unique_pids = defaultdict(set)
>>> with arcpy.da.SearchCursor(tbl, "PARCEL_NO") as cur:
...     for pid, in cur:
...         unique_pids[pid[:6]].add(pid)
...         
>>> orig_pids = set().union(*(i for i in unique_pids.values() if len(i) ==1))
>>> orig_pids
set([u'R29688011', u'R29844', u'R29842010', u'R29835', u'R29846', u'R29833'])
>>> 
RandyBurton
MVP Alum

Joshua Bixby, I always learn something from your code. Thanks.

JoeBorgione
MVP Emeritus

I'll say the same thing about you too Randy!  Both of you guys have a huge impact on what I do and how I code it!

Randy Burton

Joshua Bixby

That should just about do it....
0 Kudos
CCWeedcontrol
Frequent Contributor

I have learned a lot from all you guys on this forum.

It's nice to know there are people willing to help out!

@Joshua Bixby

@Randy Burton

@Joe Borgione

@Dan Patterson