Going through string columns and sort cell values in Pandas

Viewed 308

Suppose we have the following dataframe:

d = {'col1':['cat; banana','kiwi; orange; apple','melon'],
    'col2':['a; d; c','p; u; c','m; a'],
    'col3':[4,1,4]}
df= pd.DataFrame(d)

for all the string columns I want to sort the values alphabetically, I know how to do this column by column, namely:

df['col1'] = df['col1'].map(lambda x: '; '.join(sorted(x.split('; '))))

and similarly for col2 I wonder how one can does this for the whole dataframe? I tried to select the string objects and do the map method, but it didn't work. Namely:

df.select_dtypes(include='object').map(lambda x: '; '.join(sorted(x.split('; '))))

Update: So an inefficient way of doing this would be:

v = df.select_dtypes(include='object').applymap(lambda x: '; '.join(sorted(x.split('; '))))
w = df.select_dtypes(exclude='object')
pd.concat([v, w], axis=1)

But I am sure there are better ways.

2 Answers

You can use this trick (unpacking a dataframe and using pd.DataFrame.assign):

df.assign(**df.select_dtypes(include='object').applymap(lambda x: '; '.join(sorted(x.split('; ')))))

Output:

                  col1     col2  col3
0          banana; cat  a; c; d     4
1  apple; kiwi; orange  c; p; u     1
2                melon     a; m     4

I would do this in an inefficient for loop with a test to make sure that you are not applying it to the ints

for col in df.columns:
    if df[col].dtypes is 'str':
        df[col] = df[col].map(lambda x: '; '.join(sorted(x.split('; '))))

there maybe a better vectorized way

Related