Partage
  • Partager sur Facebook
  • Partager sur Twitter

Intervertir éléments dans np.array

Trier un array

Sujet résolu
30 juillet 2021 à 20:10:05

Bonjour,

Je dispose d'un np.array de forme (2, 9), mais le nombre de "colonnes" peut changer. Cette matrice contient des lettres en "première ligne" et des nombres (probabilités) en deuxième. J'ai alors besoin de classer les lettres par ordre de probabilités décroissant. Autrement dit, les nombres doivent se placer dans l'ordre décroissant, mais les lettres qui vont avec doivent bouger aussi.

Je peux facilement trier les nombres avec la méthode sort, voire récupérer les indices dans l'ordre avec argsort. Mais je ne vois pas comment, par la suite, placer les lettres dans l'ordre indiquer par argsort.

Auriez-vous une idée ?

Merci

  • Partager sur Facebook
  • Partager sur Twitter
31 juillet 2021 à 2:46:15

Si ta liste des indices récupérés avec argsort est dans listeIndices:
lettres[0] = [lettres[0][i] for i in listeIndices]
  • Partager sur Facebook
  • Partager sur Twitter

Le Tout est souvent plus grand que la somme de ses parties.

31 juillet 2021 à 10:11:08

Bonjour,

Merci, mais on ne peut pas passer par là car cela soulève une erreur "built_in_function is not iterable".

  • Partager sur Facebook
  • Partager sur Twitter
31 juillet 2021 à 18:48:47

Dans un np.array, les éléments ne doivent-ils pas être tous de même types?
Tu as des lettres dans la première ligne et des pourcentages dans la seconde.
Les pourcentages doivent être en format str comme mon test l'a montré.
Je n'ai pas utilisé argsort pour récolter les indices et trier la seconde ligne dans la même opération.
Dis-moi si ça correspond à ce que tu veux faire.
Je n'ai pas eu d'erreur.
-
import numpy as np
lettres=np.array([['a', 'b', 'c'],[9,6,3]])
print(lettres)
indices, lettres[1] = zip(*sorted(enumerate(lettres[1]), key=lambda t: t[1]))
print(indices)
lettres[0]=[lettres[0][i] for i in indices]
print(lettres)
-
[['a' 'b' 'c']                                                                                                         
 ['9' '6' '3']]                                                                                                        
(2, 1, 0)                                                                                                              
[['c' 'b' 'a']                                                                                                         
 ['3' '6' '9']]
  • Partager sur Facebook
  • Partager sur Twitter

Le Tout est souvent plus grand que la somme de ses parties.

1 août 2021 à 15:50:53

Bonjour,

En effet, avec le code que vous me donnez, cela fonctionne.

print(c)
def tri(array): 
    matrice = array 
    indices, matrice[1] = zip(*sorted(enumerate(matrice[1]), key = lambda t: t[1]))
    matrice[0] = [matrice[0][i] for i in indices]

    return matrice

print(tri(c))

Ce code me renvoie bien :

[['C' 'e' 'c' 'i' ' ' 's' 't' 'u' 'n']
 ['0.125' '0.25' '0.125' '0.125' '0.25' '0.1875' '0.25' '0.125' '0.125']]

[['C' 'c' 'i' 'u' 'n' 's' 'e' ' ' 't']
 ['0.125' '0.125' '0.125' '0.125' '0.125' '0.1875' '0.25' '0.25' '0.25']]

où les lettres ont bien été conservées à l'emplacement de leur probabilité et donc réarrangées pour classer les probabilités dans l'ordre.

En revanche, je ne suis pas sur de bien comprendre le fonctionnement de zip(), pourriez-vous m'expliquer ?

Il est certain que je n'aurais pu trouver seul, un grand merci.


  • Partager sur Facebook
  • Partager sur Twitter
1 août 2021 à 18:00:21

enumerate me donne des couples ou tuples (indice, valeur)
Je les trie avec une clé qui correspond à la valeur.
sorted me donne une liste des tuples qqui sont maintenant triés.
*sorted produit autant de paramètres que de tuples se trouvant dans la liste.
En fait zip fait une sorte de fusion des N tuples qu'on lui donne en paramètre.
Ce que fait zip est d'envoyer le premier élément de chaque tuple dans la première variable et l'autre élément dans la seconde.
Si je n'avais mis qu'une seule variable, j'aurais un tuple de deux éléments, le premier étant un tuple contenant tous les indices, l'autre un tuple contenant toutes les valeurs.
Illustration:
>>> i=tuple(range(1,5))                                                                                                
>>> i                                                                                                                  
(1, 2, 3, 4)                                                                                                           
>>> v=tuple(range(10,50,10))                                                                                           
>>> v                                                                                                                  
(10, 20, 30, 40)                                                                                                       
>>> m=tuple(zip(i, v))                                                                                                 
>>> m                                                                                                                  
((1, 10), (2, 20), (3, 30), (4, 40))
Ici, j'ai fait l'inverse, j'ai couplé 2 tuples de 4 éléments, ce qui me donne 4 tuples de 2 ééléments.
  • Partager sur Facebook
  • Partager sur Twitter

Le Tout est souvent plus grand que la somme de ses parties.