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
Solved! Go to Solution.
# --- 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'
# --- 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'
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.
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.
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
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")
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")
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)