1
votes

(Inverse-) Tri du tableau numpy 2D par colonne

Le code suivant trie un tableau numpy 2d dans les colonnes d'avant en arrière

import numpy as np
#Column-wise sort and inverse sort of image (2d array)
nrows = 10
ncols = 5
a = np.random.randint(nrows, size=(nrows, ncols))
a_sorted = np.sort(a, axis=0)

ori_indices = np.zeros_like(a)
for c in range(ncols):
    ori_indices[:,c] = np.argsort(np.argsort(a[:,c]))
#Do some work on sorted array, like e.g row-wise filtering
#After processing sorted array, move it back to original order
a_backsorted = np.zeros_like(a)
for c in range(ncols):
    a_backsorted[:,c] = a_sorted[:,c][ori_indices[:,c]]

print (a); print ()
print (a_backsorted); print ()
print (a_sorted); print ()

Le code fonctionne tel quel mais je suppose qu'il existe une implémentation plus efficace sans boucle for (en utilisant une indexation sophistiquée)


0 commentaires

3 Réponses :


0
votes

Vous pouvez essayer a_sorted [:: - 1] pour inverser le tableau

print (a_sorted); print ()
print (a_sorted[::-1])

[[0 0 0 2 0]
 [2 0 0 2 2]
 [4 0 2 6 4]
 [4 2 3 7 5]
 [4 4 4 7 6]
 [5 5 4 8 7]
 [6 5 4 8 7]
 [7 6 8 9 8]
 [8 7 9 9 9]
 [8 8 9 9 9]]

[[8 8 9 9 9]
 [8 7 9 9 9]
 [7 6 8 9 8]
 [6 5 4 8 7]
 [5 5 4 8 7]
 [4 4 4 7 6]
 [4 2 3 7 5]
 [4 0 2 6 4]
 [2 0 0 2 2]
 [0 0 0 2 0]]


1 commentaires

Je devrais me clarifier: il ne s'agit pas de rétablir l'ordre (croissant / décroissant), il s'agit de savoir comment inverser l'opération de tri (après la modification du tableau trié), c'est-à-dire comment inverser la permutation appliquée à chaque colonne.



0
votes
#Column-wise sort and inverse sort of image (2d array)
import numpy as np
#Define random array and sort it
nrows = 10
ncols = 5
a = np.random.randint(nrows, size=(nrows, ncols))
a_sorted = np.sort(a, axis=0)
#Save original order of columns
ori_indices = np.argsort(np.argsort(a, axis=0), axis=0)
#Do some work on sorted array, like e.g row-wise filtering.
#....
#After processing sorted array, move it back to original order:
c=np.array([[i] for i in range(ncols)]).T
a_backsorted = a_sorted[ori_indices, c]
#Check results
print (a); print ()
print (a_backsorted); print ()
print (a_sorted); print ()

2 commentaires

Bien que ce code puisse résoudre la question, y compris une explication expliquant comment et pourquoi cela résout le problème aiderait vraiment à améliorer la qualité de votre poste, et entraînera probablement plus de votes positifs. N'oubliez pas que vous répondez à la question des lecteurs à l'avenir, pas seulement à la personne qui la pose maintenant. Veuillez modifier votre réponse pour ajouter des explications et donner une indication des limitations et hypothèses applicables.


Le code ci-dessus appelle argsort deux fois, un evtl. une mise en œuvre plus efficace est dans la première réponse. Pour que l'indexation sophistiquée fonctionne, il est important que le tableau c représentant les colonnes soit une liste de listes (à un seul élément). Le fait que les indices originaux puissent être calculés via 2x argsort est un peu une torsion cérébrale, donc la première variante (appeler argsort une seule fois) est peut-être aussi plus claire. (en plus plus rapide)



0
votes
import numpy as np
nrows = 10; ncols = 5
a = np.random.randint(nrows, size=(nrows, ncols))
a_sorted = np.sort(a, axis=0)
a_backsorted = np.zeros_like(a)
c = np.array([[i] for i in range(ncols)]).T
a_backsorted[np.argsort(a, axis=0), c] = a_sorted
The reverting of the column-wise sorting is done by inserting the values of the sorted array at the argsorted positions in the backsorted array. Since this is done columnwise, the argsorted positions are paired with the columns represented in the c array

0 commentaires