'DataFrame.str.replace() vs.DataFrame.replace() quirk

Let's say I have a Series of strings I want to replace:

       Position
0       Guard
1   Forward-Center
2      Forward

I have a dict I'd like to use for the replace values:

POSITIONS = {
     'Guard':'G',
     'Forward':'F',
     'Center':'C'
  }

My desired output is

    Position
0      G
1     F-C
2      F

When I try

df.Position.replace(POSITIONS)

I get

         Position
0           G
1     Forward-Center
2           F

And when I use

df.Position.str.replace(POSITIONS)

I get a TypeError

TypeError: replace() missing 1 required positional argument: 'repl'

But when I use str.replace() without the dictionary, It works:

df.Position.str.replace('Forward','F')

         Position
0           G
1        F-Center
2           F

So I figured to get my desired output I could just chain the str.replace() together to get my desired output like so

df.Position.str.replace('Forward','F').str.replace('Guard','G').str.replace('Center','C')

But I hate chaining methods like this and it doesn't look as good as just passing a dict. Is there a way to achieve my desired output without having to chain multiple str.replace()? Why does .replace() work with the dict but str.replace() doesn't? Additionally, why doesn't .replace() take care of the hyphenated strings like str.replace()?



Solution 1:[1]

With .str.replace(), the first argument can be a regular expression, and the replacement can be a function. The function can look up the match in the dictionary.

df.Position.str.replace('|'.join(POSITIONS), lambda m: POSITIONS[m.group(0)])

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Barmar