J'ai deux ensembles de coordonnées et je veux savoir quelles coordonnées de l'ensemble coo
sont identiques à n'importe quelle coordonnée dans l'ensemble cibles
. Je veux connaître les indices dans l'ensemble coo
, ce qui signifie que je voudrais obtenir une liste d'indices ou de booléens.
[False True True False] # bool list [1,2] # list of concerning indices
Le résultat souhaité serait un des deux suivants:
import numpy as np coo = np.array([[1,2],[1,6],[5,3],[3,6]]) # coordinates targets = np.array([[5,3],[1,6]]) # coordinates of targets print(np.isin(coo,targets)) [[ True False] [ True True] [ True True] [ True True]]
Mon problème est que ...
np.isin
n'a pas d'attribut axis
pour que je puisse utiliser axis = 1
. True
pour le dernier élément, ce qui est faux. Je connais les boucles et les conditions, mais je suis sûr que Python est équipé de moyens pour une solution plus élégante.
3 Réponses :
Cette solution sera moins adaptée pour les grands tableaux , dans ce cas, les autres réponses proposées fonctionneront mieux.
Voici une façon de tirer parti de diffusion
:
(coo[:,None] == targets).all(2) array([[False, False], [False, True], [ True, False], [False, False]])
Voici une solution simple et intuitive qui utilise en fait numpy.isin ()
, pour faire correspondre les tuples , plutôt que des numéros individuels:
[False True True False] [1 2]
Le package numpy_indexed met en œuvre la fonctionnalité de ce tapez de manière vectorisée (avertissement: je suis son auteur). Malheureusement, numpy manque beaucoup de cette fonctionnalité hors de la boîte; J'ai commencé numpy_indexed avec l'intention de le fusionner dans numpy, mais il y a des problèmes de compatibilité descendante, et les gros paquets comme celui-ci ont tendance à se déplacer lentement. Cela ne s'est donc pas produit au cours des 3 dernières années; mais l'écosystème d'empaquetage python fonctionne si bien de nos jours que l'ajout d'un paquet supplémentaire à votre environnement est tout aussi simple, vraiment.
import numpy_indexed as npi bools = npi.in_(targets, coo)
Cela aura une complexité temporelle similaire à celle de la solution publiée par @fountainhead (logarithmique plutôt que linéaire, selon la réponse actuellement acceptée), mais aussi la bibliothèque npi vous donnera la sécurité des tests automatisés, et de nombreuses autres options pratiques, si vous décidez d'aborder le problème d'une manière légèrement différente angle.
Je ne suis pas sûr que la réponse actuellement acceptée ait une complexité temporelle linéaire. Lorsque nous commençons avec deux tableaux de nombres de taille 2m
et de nombres 2n
respectivement, la taille diffusée sera de 2mn
. Ainsi, la comparaison ==
des tableaux diffusés effectuera toujours une comparaison numérique de 2mn
. Ce sera toujours 2mn
des comparaisons, et pas seulement dans le pire des cas . (Le pire des cas est lorsqu'il n'y a aucune correspondance). En revanche, les solutions basées sur isin
arrêtent les correspondances supplémentaires lorsque chaque correspondance réussie se produit.
C'est linéaire à la fois en n et en m; tellement quadratique si vous mettez les deux à l'échelle en même temps. C'est en effet aussi brutal que possible, et des solutions plus intelligentes peuvent avoir un énorme avantage dans la pratique
ne devrait-il pas être l'inverse? npi.in_ (coo, cibles)? J'ai essayé votre classe et cela n'a fonctionné que de cette façon et la documentation le dit également. À votre santé.