Remove all numbers/integer values from multiple fields

117
7
Jump to solution
08-22-2019 03:33 PM
CCWeedcontrol
Regular Contributor

I have some fields with alphabetic and numbers i want to remove all the numbers. I have tried some things but the issue i have is that the numbers are between the alphabetic text for example

Homeowners field

"Homeowners 456 Exempt",---> Homeowners Exempt

"456 Homeowners Exempt"--> Homeowners Exempt

"Homeowners Exempt 456" --> Homeowners Exempt

Irrigation

Hill Irrigation #2 Dist --> Hill Irrigation Dist

#2Hill Irrigation Dist --> Hill Irrigation Dist

Hill Irrigation Dist#2 --> Hill Irrigation Dist

Drain

High Drain #2 Dist --> High Drain Dist

#2High Drain Dist --> High Drain Dist

High Drain Dist #2--> High Drain Dist

 

I have tried .strip('0123456789. -#') but it only removes them from the beginning and end not in between.

Ive been working with this but i can't seem to get right. I would appreciate any help.

fc = r"C:\Temp\Lyr1"
fields = ['HomeOwners', 'Irrigation', 'Drain']
exp = ''.join(c for c in fields if not c.isnumeric())
arcpy.management.CalculateField(fc, fields, exp, "PYTHON3")

 get the following error

RuntimeError: Object: Error in executing tool

0 Kudos
1 Solution

Accepted Solutions
DanPatterson_Retired
MVP Esteemed Contributor
# --- the key is the list of the string
# dump = list('0123456789#')
# dump
# ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#']


# --- now make the function

def dump_stuff(fld):
"""add to dump if needed"""
dump = list('0123456789#')
return "".join([i for i in fld if i not in dump])


# ---- now test it

a = "some #1 test in 234 field"
dump_stuff(a)

'some test in field'

View solution in original post

7 Replies
DanPatterson_Retired
MVP Esteemed Contributor
# --- the key is the list of the string
# dump = list('0123456789#')
# dump
# ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '#']


# --- now make the function

def dump_stuff(fld):
"""add to dump if needed"""
dump = list('0123456789#')
return "".join([i for i in fld if i not in dump])


# ---- now test it

a = "some #1 test in 234 field"
dump_stuff(a)

'some test in field'

View solution in original post

CCWeedcontrol
Regular Contributor

I was always told to avoid functions when using field calculator and therefor never done it. So i am not sure how to use the function with field calculator.

0 Kudos
DanPatterson_Retired
MVP Esteemed Contributor

It need not be a field calculator expression.  You can call that def within a loop that collects all your text fields in a featureclass.  Pass the field's name to the function and it work  with an updatecursor or the field calculator call as Joshua indicated.  The key is the function.

0 Kudos
CCWeedcontrol
Regular Contributor

I was able to get to work with arcpy.da.UpdateCurosr.

def dump_stuff(fld):
"""add to dump if needed"""
dump = list('0123456789#')
return "".join([i for i in fld if i not in dump])

with arcpy.da.UpdateCursor(fc, fld) as cursor:
for row in cursor:
s = row[0]
row[0] = dump_stuff(row[0])
row[1] = dump_stuff(row[1])
row[2] = dump_stuff(row[2])
cursor.updateRow(row)
del cursor
0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Speaking just to the code snippet you provided, the Field Calculator acts on one field at a time, you can't pass it a list of fields to operate on independently.  If you want to process multiple fields using the same method/approach, you will need to loop over a list of fields and call Field Calculate on each one.

fc = r"C:\Temp\Lyr1"
fields = ['HomeOwners', 'Irrigation', 'Drain']

for fld in fields:
exp = # some expression that is formatted correctly
arcpy.management.CalculateField(fc, fld, exp, "PYTHON3")
CCWeedcontrol
Regular Contributor

Based on what you stated that you can't pass a list of fields. Here is what i came up with, correct?

This took about 2.06 mins where using arcpy.da.UpdateCursor only took 4 seconds. The only issue with the code below is that it removed everything that was not alphabet character but it didn't leave a space, like so. I need there to be a space.

Drain

High Drain #2 Dist --> HighDrainDist

#2High Drain Dist --> HighDrainDist

High Drain Dist #2--> HighDrainDist

code I used.

fc = r"C:\Temp\Lyr1"
fields = ['HomeOwners', 'Irrigation', 'Drain']

for fld in fields:
exp = "''.join([i for i in !HomeOwners! if i.isalpha()])"
arcpy.management.CalculateField(fc, 'HomeOwners', exp, "PYTHON3")

exp = "''.join([i for i in !Irrigation! if i.isalpha()])"
arcpy.management.CalculateField(fc, 'Irrigation', exp, "PYTHON3")

exp = "''.join([i for i in !Drain! if i.isalpha()])"
arcpy.management.CalculateField(fc, 'Drain', exp, "PYTHON3")
0 Kudos
JoshuaBixby
MVP Esteemed Contributor

Try:

"''.join([i for i in !Irrigation! if any((i.isalpha(), i.isspace()))]).strip()"

(and, by the way, I think you have already shown using a cursor is much more efficient)