How to add "orderd data" wity apply method in pandas (not use for-loop)

Question:

ID A B C D Orderd
No1 8 9 5 2 D:2 C:5 A:8 B:9
No2 3 1 7 9 B:1 A:3 C:7 D:9
No3 29 34 5 294 C:5 A:29 B:34 D:294

I would like to add "Orderd" column with column of A, B, C and D.

If I use for loop, I can do it as like

for n in range(len(df)):
    df['Orderd'][n] = df.T.sort_values(by=n,ascending=True)[n].to_string()

However, this method is too slow. I would like to do like this with "df.apply" method for doing speedy.

Asked By: aaaaa0a

||

Answers:

you can use apply directly on your dataframe, indicating the axis = 1

import pandas as pd

columns = ["ID","A","B","C","D"]
data = [["No1",8,9,5,2],
        ["No2",3,1,7,9],
        ["No3",29,34,5,294]]

df = pd.DataFrame(data=data, columns=columns)
df = df.set_index("ID") # important to avoid having an error

df["Orderd"] = df.apply(lambda x: x.sort_values().to_dict(), axis=1)

outputs:

   A   B   C   D   Orderd
ID                  
No1     8   9   5   2   {'D': 2, 'C': 5, 'A': 8, 'B': 9}
No2     3   1   7   9   {'B': 1, 'A': 3, 'C': 7, 'D': 9}
No3     29  34  5   294     {'C': 5, 'A': 29, 'B': 34, 'D': 294}
Answered By: Lucas M. Uriarte

I managed to do it like this:

df['Ordered'] = df.apply(lambda row: ' '.join([':'.join(s) for s in dict(row[1:].sort_values().astype('str')).items()]), axis=1)

Basically, I take all values in the row excluding the first one, which gives you a series. I sort it and convert to string.Then I convert the series to an dict and retrieve the items. I then use two list comprehensions to first join the Letter-Value pairs with a colon and then join the pair strings with a space.

Answered By: sunnytown
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.