Multiple replacements with Field Calculations using Python

9718
15
Jump to solution
08-26-2015 06:18 AM
Labels (1)
LeonardSpringer
New Contributor

I am able to make replacements one at a time following these instructions:

Simple calculations

Simple string examples

Strings are supported by a series of Python string functions, including capitalize, rstrip, and replace.

Replace any occurrences of "california" with "California" found in the field STATE_NAME.

!STATE_NAME!.replace("california", "California")

How do I make several replacements at a time? For example, how do I change “california” and “cal” and “CA” and “Cal” to “California” and “florida” and “fla” and “FL” and “Fla” to “Florida” without having to create a new field for STATE NAME for each individual replacement?

Thanks, Len Springer

0 Kudos
1 Solution

Accepted Solutions
IanMurray
Frequent Contributor

I used a function to do something like this and it should be adaptable for what you are needing.  I had a table with mixed upper and lower cases no's and Nones, that I all wanted "No".  Also replaced all "yes" with "Yes".  The function allows you to use loops and other python tools, instead of a single line of code.

If you know all the exact strings you need replaced, you can put them in lists, otherwise wildcards could be used.

Python Parser, click Show Code Block


Pre-Logic Script Code

def Rename(field):
  type1_replace = [ "no" , "None"]
  type2_replace = "yes"
  for n in type1_replace:
    field = field.replace(n , "No")
  field = field.replace(type2_replace , "Yes")
  return field

New Field = Rename(!YourFieldHere!)

Edit: Ah heck, I'll post a relevant to you example.

def Rename(field):
  type1_replace = ["california" ,  "CA" , "cal" ]
  type2_replace = [ "florida" , "FL" , "fl"]
  for n in type1_replace:
    field = field.replace(n , "California")
  for n2 in type2_replace:
    field = field.replace(n2 , "Florida")
  return field

View solution in original post

15 Replies
ChrisDonohue__GISP
MVP Alum

Just an idea - I guess part of this could come down to whether one could use wildcards in Python.  I don't know the exact answer, but can outline the concept.  For example, if you know your data will only include state names expressed in various abbreviations, something like:

!STATE_NAME!.replace("ca#", "California")

where # is the wildcard allowing unlimited characters after it (whatever the appropriate Python wildcard would be).

I'm pretty sure the Python Guru's here on GeoNet would know.  I'm curious to see what folks come up with.

Chris Donohue, GISP

0 Kudos
ChrisDonohue__GISP
MVP Alum

A quick search revealed this thread regarding Python wildcards.  Apparently in Python * is the one for 'one or more characters'.

They also mention other ways to do the search that may be usable.

http://stackoverflow.com/questions/11427138/python-wildcard-search-in-string

Chris Donohue, GISP

0 Kudos
ChrisDonohue__GISP
MVP Alum

Hmmm, maybe it is time to call in some Python experts:

Xander Bakker

Dan Patterson

Darren Wiens

Chris Donohue, GISP

0 Kudos
IanMurray
Frequent Contributor

I used a function to do something like this and it should be adaptable for what you are needing.  I had a table with mixed upper and lower cases no's and Nones, that I all wanted "No".  Also replaced all "yes" with "Yes".  The function allows you to use loops and other python tools, instead of a single line of code.

If you know all the exact strings you need replaced, you can put them in lists, otherwise wildcards could be used.

Python Parser, click Show Code Block


Pre-Logic Script Code

def Rename(field):
  type1_replace = [ "no" , "None"]
  type2_replace = "yes"
  for n in type1_replace:
    field = field.replace(n , "No")
  field = field.replace(type2_replace , "Yes")
  return field

New Field = Rename(!YourFieldHere!)

Edit: Ah heck, I'll post a relevant to you example.

def Rename(field):
  type1_replace = ["california" ,  "CA" , "cal" ]
  type2_replace = [ "florida" , "FL" , "fl"]
  for n in type1_replace:
    field = field.replace(n , "California")
  for n2 in type2_replace:
    field = field.replace(n2 , "Florida")
  return field
LeonardSpringer
New Contributor

Thank you, Ian. That works for me.

0 Kudos
IanMurray
Frequent Contributor

Also, why would you need to create a new field each time?  You could run the field calculator over and over again on the existing field if you wanted.  Calculate Field can be done on an existing field or a new empty field. 

0 Kudos
ChrisDonohue__GISP
MVP Alum

Thanks for the code example, Ian.

In regards to the new fields, I think Leonard means making a new line for each replacement, not the literal making a new field.  For example, having to do this to account for all the possible combinations:

!STATE_NAME!.replace("california", "California")

!STATE_NAME!.replace("ca", "California")

!STATE_NAME!.replace("cal", "California")

!STATE_NAME!.replace("cali", "California")

etc....

Chris Donohue, GISP

0 Kudos
DarrenWiens2
MVP Honored Contributor

You can do this using a dictionary, where the key is the state name, and the value is a list of possible matches:

def customReplace(search):
    dict = {'California':['c','ca','cal'], 'Florida': ['f','flor','fla']} # build your custom dictionary
    for k,v in dict.iteritems(): # loop through key/value pairs
        for abbrev in v: # loop through the abbreviation list
            if search == abbrev: # compare
                return k # return the state
    return search # else return original
ChrisDonohue__GISP
MVP Alum

Darren - is there also a way to do wildcards instead of a dictionary?  Like if the values to be evaluated can only be state names, so any combination starting with "Wy...." is going to be "Wyoming".  This would save having to type out every possible combination people use to abbreviate Wyoming (and other states).

Chris Donohue, GISP

0 Kudos