8
votes

Transformer un ensemble de nombres en numpy afin que chaque numéro soit converti en un certain nombre d'autres numéros inférieurs à celui qu'il

considérer un ensemble de nombres: xxx pré>

maintenant je veux transformer cet ensemble dans un autre ensemble y code> de la manière suivante: pour chaque élément i code> dans x code>, l'élément correspondant j code> dans y code> serait le nombre d'autres éléments dans x code> qui sont moins que i code>. Par exemple, ce qui précède donné x code> ressemblerait à: p> xxx pré>

maintenant, je peux faire cela à l'aide de simples boucles Python: P>

In [19]: z = x[x < 0.5]

In [20]: z
Out[20]: array([ 0.03255799,  0.03050498,  0.01951657,  0.04767246,  0.3617409 ])


4 commentaires

Notez que votre entrée est juste np.random.rand (10) .


@Andrasdeak: Je ne t'ai pas eu.


Essayez x = np.random.rand (10) et vous verrez que vous n'avez pas à appeler aléatoire () dans une liste Comp :)


Oui bien sûr! Merci :) Mes vraies données n'est pas aléatoire cependant.


4 Réponses :


11
votes

Ce que vous devez réellement faire est d'obtenir le inverse de l'ordre de tri de votre tableau: xxx

exemple exécutif (à Ipython): xxx


alternativement, si vous souhaitez obtenir le nombre d'éléments plus grand que chaque élément correspondant dans x , vous devez inverser le tri de l'ascension à la descente. Une option possible de faire cela est de simplement échanger la construction de l'indexation: xxx

un autre, Comme @unutbu suggéré dans un commentaire , est Pour cartographier le tableau d'origine sur le nouveau: xxx


12 commentaires

Ou juste argsort deux fois: x.argsort (). Argsort () ?


@Divakar Naturellement, vous avez raison. Mais je n'ai jamais vu cette approche :) Voulez-vous l'ajouter comme une réponse?


@Divakar: y [np.argsort (x)] = np.arange (x.size) est plus rapide


@Andrasdeak: Pour obtenir le Y , l'OP aurait besoin de y = x.size-y-1 .


@unutbu, je pense toujours dans le sens de votre commentaire maintenant supprimé sur la question. L'exemple de sortie de l'OP ne contredit pas leur spécification?


@Andrasdeak: Ou, l'OP pourrait conserver l'exemple, mais modifier le texte à lire: "Y serait le nombre d'autres éléments de x qui sont plus grand que moi".


@unutbu Regardez le dernier élément de x dans mon exemple: c'est la plus petite valeur dans x , donc 0 éléments sont inférieurs à cela. Correspondant, y a 0 dans cette position. Où est-ce que je vais mal?


@Andrasdeak: Je pense que votre réponse est correcte. Il est cohérent avec le texte de la question de l'OP et son code . C'est l'exemple qui devrait être changé.


@unutbu ah ok, merci pour la clarification. J'ai ajouté deux versions pour faire cet ordre inverse (l'un est le vôtre).


@Divakar vient de me référer à ce message de Stackoverflow.com/a/41394980/2336654 . Méthode brillante.


£quared merci (je vais devoir le remercier pour la publicité;))


J'ai ajouté des horaires si vous êtes intéressé.



5
votes

Voici une approche en utilisant np.searchsorted code> - xxx pré>

autre basé sur @Andras Decak's Solution Code> à l'aide de Argsort () Code> - P>

In [359]: x
Out[359]: 
array([ 0.62594394,  0.03255799,  0.7768568 ,  0.03050498,  0.01951657,
        0.04767246,  0.68038553,  0.60036203,  0.3617409 ,  0.80294355])

In [360]: np.searchsorted(np.sort(x),x)
Out[360]: array([6, 2, 8, 1, 0, 3, 7, 5, 4, 9])

In [361]: x.argsort().argsort()
Out[361]: array([6, 2, 8, 1, 0, 3, 7, 5, 4, 9])


1 commentaires

J'ai ajouté des horaires si vous êtes intéressé.



2
votes

En plus des autres réponses Une autre solution à l'aide d'une indexation booléenne pourrait être la suivante: xxx

pour votre exemple: xxx


1 commentaires

D'une manière vectorisée: (x [:, aucun]> x) .sum (1) .



2
votes

Je voulais contribuer à ce poste en fournissant des tests sur la solution de @andras Decak versus argsort à nouveau.

Il semblerait que argrsort est à nouveau plus rapide pour les tableaux courts. Une idée simple est d'évaluer quelle est la durée de la matrice dans laquelle nous voyons le décalage de la balance.

Je définirai trois fonctions


1 commentaires

Bon terrain de mort!