¿Cómo hacer que el resultado argsort sea aleatorio entre valores iguales?

Digamos que tienes un vector numpy [0,3,1,1,1] y ejecutas argsort obtendrás [0,2,3,4,1] pero todos son iguales! Lo que quiero es una forma eficiente de barajar índices de valores idénticos. ¿Alguna idea de cómo hacerlo sin un bucle while con dos índices en el vector ordenado?

 numpy.array([0,3,1,1,1]).argsort() 

Use lexsort : np.lexsort((b,a)) significa Ordenar por a , luego por b

 >>> a array([0, 3, 1, 1, 1]) >>> b=np.random.random(a.size) >>> b array([ 0.00673736, 0.90089115, 0.31407214, 0.24299867, 0.7223546 ]) >>> np.lexsort((b,a)) array([0, 3, 2, 4, 1]) >>> a.argsort() array([0, 2, 3, 4, 1]) >>> a[[0, 3, 2, 4, 1]] array([0, 1, 1, 1, 3]) >>> a[[0, 2, 3, 4, 1]] array([0, 1, 1, 1, 3]) 

Esto es un poco difícil, pero si su matriz solo contiene números enteros, puede agregar valores aleatorios y presentar el resultado. np.random.rand le da resultados en [0, 1) por lo que en este caso se le garantiza que mantendrá el orden de los elementos no idénticos.

 >>> import numpy as np >>> arr = np.array([0,3,1,1,1]) >>> np.argsort(arr + np.random.rand(*arr.shape)) array([0, 4, 3, 2, 1]) >>> np.argsort(arr + np.random.rand(*arr.shape)) array([0, 3, 4, 2, 1]) >>> np.argsort(arr + np.random.rand(*arr.shape)) array([0, 3, 4, 2, 1]) >>> np.argsort(arr + np.random.rand(*arr.shape)) array([0, 2, 3, 4, 1]) >>> np.argsort(arr + np.random.rand(*arr.shape)) array([0, 2, 3, 4, 1]) >>> np.argsort(arr + np.random.rand(*arr.shape)) array([0, 4, 2, 3, 1]) 

Aquí vemos que el índice 0 siempre es el primero en el resultado de argsort y el índice 1 es el último, pero el rest de los resultados están en un orden aleatorio.

En general, podría generar valores aleatorios delimitados por np.diff(np.sort(arr)).max() , pero podría tener problemas de precisión en algún momento.