How to reverse strings in pandas dataframe?

Viewed 3163

My dataframe is like,

ID   col1
1    Michael Owen
2    Stephen Curry
3    Messi, Lionel
4    James, LeBron

I tried to reverse the order of those names which were split by ", " .

My code is,

df['col1'] = df.col1.str.split().apply(lambda x: ', '.join(x[::-1]))

But it reverses all rows even the names were split by " ".

ID   col1
1    Owen, Michael
2    Curry, Stephen
3    Lionel, Messi
4    LeBron, James

Then I tried

df.loc[df['col1'].str.contains(", ").split("col1")].apply(lambda x: ', '.join(x[::-1]))

It gives me an error,

AttributeError: 'Series' object has no attribute 'split'

How can I solve this problem?

5 Answers

Use Series.where:

df['col1']=( df.col1.str.split()
              .apply(lambda x: ', '.join(x[::-1]).rstrip(','))
              .where(df['col1'].str.contains(','),df['col1']) )

   ID           col1
0   1   Michael Owen
1   2  Stephen Curry
2   3  Lionel, Messi
3   4  LeBron, James

If you want drop ','

df['col1']=( df.col1.str.split()
              .apply(lambda x: ', '.join(x[::-1]).rstrip(','))
              .where(df['col1'].str.contains(','),df['col1']) 
              .str.replace(',','') )

   ID           col1
0   1   Michael Owen
1   2  Stephen Curry
2   3  Lionel  Messi
3   4  LeBron  James

It gives me an error,

This is because str.contains(", ") returns a boolean series, and it has no method split.

In any case, try

df.col1.str.split(',').str[1] + ',' + df.col1.str.split(',').str[0]

To fix your code np.where

df['col1']=np.where(df.col1.str.contains(','),df.col1.str.split(', ').apply(lambda x: ', '.join(x[::-1])),df.col1)

You just have to put in a comma into the split() like so:

df['col1'] = df.col1.str.split(',').apply(lambda x: ', '.join(x[::-1]))

If you want to reverse and drop the ',' then remove it from the join method.

df['col1'] = df.col1.str.split(',').apply(lambda x: ' '.join(x[::-1]))

I chose to present the final values without the comma. If you need a comma, change the join string from ' ' to ', '. I added these answers because:

  1. There is no need to use apply in order to reverse the list when str[::-1] does the job
  2. There is no need to use apply or any other trick when splitting on comma ',' will produce a list either way and reversing a one element list is the same list. That implies that my method is safe to run on the names with no commas. I don't need an if/then construct.
  3. I deal with potential spaces in two different ways.
    1. With regex
    2. With str.strip

Regex and pandas.Series.str ...

... chained 3 times

#                          regex expression  
#                          split on comma
#                          followed by zero
#                          or more spaces
#                               /--\
df['col1'] = df.col1.str.split(',\s*').str[::-1].str.join(' ')

df

   ID           col1
0   1   Michael Owen
1   2  Stephen Curry
2   3   Lionel Messi
3   4   LeBron James

comprehension and str.strip

df['col1'] = [' '.join([*map(str.strip, x.split(','))][::-1]) for x in df.col1]

df

   ID           col1
0   1   Michael Owen
1   2  Stephen Curry
2   3   Lionel Messi
3   4   LeBron James
Related