Similaire à retrun_inverse dans numpy.unique,

Si j'ai un tableau numpy a: [['a' 'b'] ['b' 'c'] ['c' 'c'] ['c' 'b']],

Je veux convertir le tableau b: [['b' 'c'] ['a' 'b'] ['c' 'c'] ['a' 'b'] ['c' 'c']] en [1 0 2 0 2].

Existe-t-il un moyen intelligent de le convertir?

0
rymuff 21 mai 2020 à 13:08

3 réponses

Une façon intéressante de faire les choses, peut-être?

a.append(None)
aa = np.array(a)[:-1]                # Note 1

b.append(None)
bb = np.array(b)[:-1]

ind_arr = bb[:, None] == aa          # Note 2
np.nonzero(ind_arr)[1]

Remarque 1 : La première étape ressemble plus à une surcharge pour obtenir un tableau object de type 1-D. Sinon, numpy force un tableau de type 2-D str, ce qui n'est pas utile pour cette application. Pour en savoir plus, consultez cette réponse. Il énonce également quelques alternatives.

Remarque 2 : Cela crée un masque booléen 2D avec chaque élément de aa comparé à chaque élément de bb pour égalité , comme ceci: ind_arr[i, j] = (bb[i] == aa[j]).
La ligne suivante utilise ce masque et extrait les valeurs True le long de l ' axe 1 (là où la comparaison était évaluée à True). En effet, les valeurs aa du masque de comparaison sont le long de l'axe 1.
Une autre discussion pour mieux comprendre cela.

Si vous recherchez de la vitesse, pour les listes , la réponse de norok2 est beaucoup plus rapide. Cela peut peut-être avoir des applications innovantes. À votre santé!

0
amzon-ex 21 mai 2020 à 13:37

Ce n'est pas la solution la plus élégante, mais cela fonctionne:

Mise en place (à l'avenir, montrez le code pour générer votre exemple, cela accélérera la réponse):

import numpy as np
a = np.array([['a', 'b'], ['b', 'c'], ['c', 'c'], ['c', 'b']])
b = np.array([['b', 'c'], ['a', 'b'], ['c', 'c'], ['a', 'b'], ['c', 'c']])
desired_output = [1, 0, 2, 0, 2]

Utilisation de la fonction numpy.where (comme dans cette question connexe : Est existe-t-il une fonction NumPy pour renvoyer le premier index de quelque chose dans un tableau?)

Nous utilisons np.where par élément dans chaque ligne, multiplions les résultats booléens et utilisons la compréhension de liste pour passer ligne par ligne:

output = [np.where((x[0]==a[:,0]) * (x[1]==a[:,1]))[0][0] for x in b]

Il rend le résultat souhaité.

0
Itamar Mushkin 21 mai 2020 à 10:43

Peut-être que cela est plus facile à faire avec des list s simples (que vous pouvez obtenir à partir de tableaux NumPy avec la méthode .tolist()):

a = [['a', 'b'], ['b', 'c'], ['c', 'c'], ['c', 'b']]
b = [['b', 'c'], ['a', 'b'], ['c', 'c'], ['a', 'b'], ['c', 'c']]

print([a.index(x) for x in b])
# [1, 0, 2, 0, 2]
1
norok2 21 mai 2020 à 10:50