1

Say we define a function for doing argsort with support for ties as described in this solution:

def argsort_with_support_for_ties(a):
  rnd_array = np.random.random(a.size)
  return np.lexsort((rnd_array,a))

We test it on:

input  = np.array([5.5, 3.5, 2.0, 2.0, 7.0, 7.0, 7.0, 3.5, 6.5, 6.5, 6.5, 9.0])
output = argsort_with_support_for_ties(input)

with he following result:

> np.stack([input, output], axis=0).T

array([[  5.5,   3. ],
       [  3.5,   2. ],
       [  2. ,   1. ],
       [  2. ,   7. ],
       [  7. ,   0. ], <--- A
       [  7. ,  10. ], <--- B
       [  7. ,   9. ],
       [  3.5,   8. ],
       [  6.5,   5. ],
       [  6.5,   4. ],
       [  6.5,   6. ],
       [  9. ,  11. ]])

Note how entries A and B shared the same input value (7), but ended up in vastly different locations 0 and 10.

This is not what I was hoping to get. A more acceptable answer would have been:

output  = np.array([4, 2, 1, 0, 8, 9, 10, 3, 5, 6, 7, 11])

So what failed above with argsort_with_support_for_ties?

Community
  • 1
  • 1
Amelio Vazquez-Reina
  • 91,494
  • 132
  • 359
  • 564
  • 1
    Take a look at `input[output]`, doesn't it give a sorted array? – wrwrwr Nov 28 '16 at 23:14
  • 1
    You are interpreting the result of `lexsort` incorrectly. It is not the ranking of the values. It holds the indices such that `input[output]` is the sorted array. For example, your result shows `output[4]` is 0. That means that in the sorted result, the value at index 4 is taken from the input at index 0. – Warren Weckesser Nov 28 '16 at 23:25
  • 1
    If you want to rank the values, see http://stackoverflow.com/questions/5284646/rank-items-in-an-array-using-python-numpy – Warren Weckesser Nov 28 '16 at 23:27

1 Answers1

1

I understand that you want to rank the elements so that the tiebreaking is random. For this you just need to invert the permutation that you got from lexsort:

output = np.argsort(np.lexsort((rnd_array,a)))

My output (which is not identical to yours because of randomness):

array([ 4,  3,  0,  1, 10,  9,  8,  2,  7,  5,  6, 11])