MATLAB-style find() en Python
Dans MATLAB, il est facile de trouver les indices des valeurs qui satisfont à une condition particulière:
>> a = [1,2,3,1,2,3,1,2,3];
>> find(a > 2) % find the indecies where this condition is true
[3, 6, 9] % (MATLAB uses 1-based indexing)
>> a(find(a > 2)) % get the values at those locations
[3, 3, 3]
Quelle serait la meilleure façon de le faire en Python?
Jusqu'à présent, je suis venu avec la suivante. Juste obtenir les valeurs:
>>> a = [1,2,3,1,2,3,1,2,3]
>>> [val for val in a if val > 2]
[3, 3, 3]
Mais si je veux l'index de chacune de ces valeurs, il est un peu plus compliqué:
>>> a = [1,2,3,1,2,3,1,2,3]
>>> inds = [i for (i, val) in enumerate(a) if val > 2]
>>> inds
[2, 5, 8]
>>> [val for (i, val) in enumerate(a) if i in inds]
[3, 3, 3]
Est-il une meilleure façon de le faire en Python, en particulier pour arbitraire conditions (pas juste "val > 2')?
J'ai trouvé des fonctions équivalentes à MATLAB "trouver" dans NumPy mais je n'ont pas actuellement accès à ces bibliothèques.
- Votre dernier exemple pourrait être
[a[i] for i in inds]
, ce qui est un peu plus simple.
Vous devez vous connecter pour publier un commentaire.
Vous pouvez faire une fonction qui prend un callable paramètre qui sera utilisé dans la partie conditions de votre compréhension de liste. Ensuite, vous pouvez utiliser un lambda ou une autre fonction de l'objet de transmettre à l'arbitraire de l'état:
C'est un peu plus près à vos Matlab exemple, sans avoir à charger tout de numpy.
inds = [i for (i, val) in enumerate(a) if val > 2]
qui est une solution en ligne.dans numpy vous avez
where
:x[x>3]
au lieu denp.where(x>3)
) (Pas qu'il y ait quelque chose de mal avecwhere
! L'indexation directe est peut-être une plus forme familière aux personnes familières avec Matlab.)where
renvoie en fait des indices, au moins dans la version 1.6.1. Il peut renvoyer des valeurs si vous spécifier que c'est le deuxième argument. De docs surargwhere
: "La sortie de argwhere n'est pas adapté pour l'indexation des tableaux. Pour cela, où(a) à la place."x = np.arange(9)
, ce qui en soi est un ensemble d'indices. Si vous modifiez le tableau (décalage, mise à l'échelle, l'inverser, etc.), la sortie dewhere
sera toujours indices: >>> x = np.arange(9)[::-1] * 10 + 33; print(x); print(np.où(x > 53)); [113 103 93 83 73 63 53 43 33] (tableau([0, 1, 2, 3, 4, 5]),)where
est en fait de donner des indices, et non des valeurs. L'exemple n'était pas approprié. Je vais modifier la question pour résoudre le problème dès que possible. Personne ne l'avait vu qu'avant. Incroyable.Ou utiliser numpy est différente de zéro de la fonction:
Pourquoi ne pas simplement utiliser ce:
ou arbitraires conditions, de définir une fonction
f
de votre condition et de faire:La
numpy
routine plus couramment utilisé pour cette application estnumpy.où()
; cependant, je crois qu'il fonctionne de la même commenumpy.différent de zéro()
.Pour obtenir les valeurs, vous pouvez stocker les indices et tranche avec eux:
ou vous pouvez passer le tableau comme paramètre facultatif:
ou plusieurs tableaux:
Pour obtenir des valeurs arbitraires conditions, vous pouvez utiliser
filter()
avec une fonction lambda:L'une des voies possibles pour obtenir les indices serait d'utiliser
enumerate()
de construire un n-uplet avec à la fois des indices et des valeurs, et puis filtre:filter
, mais en utilisant des interprétations de la liste est préférable et plus hautement optimisé.J'ai essayé de trouver un moyen rapide de faire cette chose exacte, et voici ce que je suis tombé sur une (utilisation de numpy pour la rapidité de vecteur de comparaison):
Il s'avère que c'est beaucoup plus rapide que:
Il semble que Python est plus rapide en comparaison lorsqu'il est effectué dans un tableau numpy, et/ou plus rapides à faire des interprétations de la liste lors de la simple vérification de la vérité plutôt que de la comparaison.
Edit:
J'ai été revoir mon code et je suis tombé sur un peut-être moins gourmande en mémoire, peu plus rapide, et super-concise façon de le faire en une seule ligne:
Je pense que j'ai peut-être trouvé un moyen rapide et simple de substitution.
BTW, j'ai senti que le np.où() la fonction n'est pas très satisfaisante, en un sens, que quelque part, il contient un ennuyeux ligne de zéro-élément.
Meilleur,
Da
Matlab trouver le code a deux arguments. Jean du code de comptes pour le premier argument, mais pas le second. Par exemple, si vous voulez savoir où l'indice de la condition est satisfaite: Mtlab de la fonction:
L'aide de Jean-code, tout ce que vous avez à faire est d'ajouter un [x] à la fin des indices de la fonction, où x est le numéro d'index que vous cherchez.
qui renvoie >>> 2, le premier indice de dépasser de plus de 2.