0

I constructed a dataframe which looks like this:

title category1 category2 category3 category4
'a'    0.44214    NAN        0.99     0.35
'b'      NAN      NAN        NAN       NAN
'c'      0.31      0.41       0.5       0.53

For each row, I want to indicate the two highest values with 1 and all others with 0.

Result should look like this:

 title category1 category2 category3 category4
'a'    1           0          1         0
'b'    0           0          0         0
'c'    0           0          1         1

Is there a buildin-function solve this or how could this be implemented otherwise?

2
  • 1
    What if the numbers are 0.9, 0.9, 0.8, 0.8? What would you want to happen? What if the numbers are 0.9, 0.9, 0.9, 0.8? (In other words, how do you want to handle ties?) Commented Dec 18, 2015 at 17:01
  • Very unlikely case because these numbers are random floats. But if it happens it should take two of these highest numbers and replace them with 1 Commented Dec 18, 2015 at 17:07

1 Answer 1

2

You can rank the rows (setting axis=1) in descending order all numeric values in the dataframe. Then do a boolean comparison to find the rank values less than or equal to two (le(2)), which would be rank values 1 and 2. Finally, convert the boolean mask to integers.

>>> df.rank(axis=1, ascending=False, numeric_only=True).le(2).astype(int)
       category1  category2  category3  category4
title                                            
'a'            1          0          1          0
'b'            0          0          0          0
'c'            0          0          1          1
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for your help but unfortunately your solutions seems not to work. Printing the result returns : Empty DataFrame Columns: [] Index: [0, 1]
Are you sure your dataframe contains values instead of text? What is the output of df.info()?
Oh you're right. Thanks. I converted to dtype=float and everything works fine. Really fancy solution. Thanks

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.