Reputation: 96360
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
?
Upvotes: 1
Views: 530
Reputation:
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])
Upvotes: 1