Should I use Series.replace or Series.str.replace?

Viewed 493

Let's say that I have a series like this one:

u = pandas.Series(['foo', 'bar'])

I'd like to perform a simple regex replacement.

Should I favor u.replace('o+', '', regex = True) or u.str.replace('o+', '')?

I've never observed any performance difference, and looking at the docs, Series.replace seems to be far more general than Series.str.replace. So what's the raison d'ĂȘtre of the latter?

2 Answers

I will provide a more general answer addressing the differences between replace and str.replace. It seems to me that indeed replace is more useful in most cases. I illustrate five differences using the following simple dataframe.

import pandas as pd
import numpy as np
df1 = pd.DataFrame({'object':[123,'123','123abc','abc','a',2],
                    'integer':[123,456,789,1,2,3]})
print(df1.dtypes)

First, 'str.replace' is a Series method only but 'replace' is both a Series and a DataFrame method. So, while 'str.replace' can only be applied to one variable or column at a time, 'replace' can be applied to an entire dataframe in one go.

df2 = df1.str.replace(2, '') # throws error
df2 = df1.replace(2, '') # works without issues
print(df1,'\n\n',df2)

Second, 'str.replace' does not work on integers and floats but 'replace' does. This should be obvious given the 'string' nature of the method, but I am nevertheless showing it to be comprehensive.

df1['integer1'] = df1['integer'].str.replace(2,'') # throws error
df1['integer2'] = df1['integer'].replace(2,'') # replaces with blank, but leads to variable converting to object type
df1['integer3'] = df1['integer'].replace(2,np.nan) # replaces with blank, but leads to variable converting to float type
print(df1)
print(df1.dtypes)

Third, 'str.replace' cannot replace values with np.nan but 'replace' can.

df1['object1'] = df1['object'].str.replace('a',np.nan) # throws error
df1['object2'] = df1['object'].replace('a',np.nan) # replaces with np.nan; object type remains as is
print(df1.drop('integer', axis=1))
print(df1.dtypes)

Fourth, 'str.replace' will replace substrings by default whereas 'replace' will replace whole words. This is because 'regex=True' by default for 'str.replace' whereas regex=False by default for 'replace'. Also, 'str.replace' replaces integers and floats with np.nan in process. 'replace' does not do that.

df1['object1'] = df1['object'].str.replace('a','')
df1['object2'] = df1['object'].replace('a','')
print(df1.drop('integer', axis=1))

Fifth, to replace substrings using 'replace', we must use regex=True. As we have seen in the previous example, regex=True is not necessary for 'str.replace' because it is already turned on by default.

df1['object1'] = df1['object'].str.replace('a','', regex=True) # same result as without regex=True
df1['object2'] = df1['object'].replace('a','', regex=True) # not the same result as without regex=True
print(df1.drop('integer', axis=1))
Related