Question

Quelqu'un a-t-il déjà rencontré ce problème? Disons que vous avez deux tableaux comme celui-ci

a = array([1,2,3,4,5,6])
b = array([1,4,5])

Existe-t-il un moyen de comparer les éléments d’un élément existant dans b? Par exemple,

c = a == b # Wishful example here
print c
array([1,4,5])
# Or even better
array([True, False, False, True, True, False])

J'essaie d'éviter les boucles, car cela prendrait des siècles avec des millions d'éléments. Des idées?

A bientôt

Était-ce utile?

La solution

En fait, il existe une solution encore plus simple que celles-ci:

import numpy as np

a = array([1,2,3,4,5,6])
b = array([1,4,5])

c = np.in1d(a,b)

Le c résultant est alors:

array([ True, False, False,  True,  True, False], dtype=bool)

Autres conseils

Utilisez np.intersect1d.

#!/usr/bin/env python
import numpy as np
a = np.array([1,2,3,4,5,6])
b = np.array([1,4,5])
c=np.intersect1d(a,b)
print(c)
# [1 4 5]

Notez que np.intersect1d donne la mauvaise réponse si a ou b ont des éléments non uniques. Dans ce cas, utilisez np.intersect1d_nu.

Il existe également np.setdiff1d, setxor1d, setmember1d et union1d. Voir Liste d'exemples Numpy avec Doc

Merci pour votre réponse, kaizer.se. Ce n'est pas tout à fait ce que je cherchais, mais avec une suggestion d'un ami et ce que vous avez dit, j'ai proposé ce qui suit.

import numpy as np

a = np.array([1,4,5]).astype(np.float32)
b = np.arange(10).astype(np.float32)

# Assigning matching values from a in b as np.nan
b[b.searchsorted(a)] = np.nan

# Now generating Boolean arrays
match = np.isnan(b)
nonmatch = match == False

C’est un processus un peu fastidieux, mais il est plus efficace que d’écrire en boucle ou de tisser avec des boucles.

A bientôt

Numpy a une fonction définie numpy.setmember1d () qui fonctionne sur les tableaux triés et uniques et renvoie exactement le tableau booléen souhaité. Si les tableaux d'entrée ne correspondent pas aux critères, vous devez convertir le format défini et inverser la transformation sur le résultat.

import numpy as np
a = np.array([6,1,2,3,4,5,6])
b = np.array([1,4,5])

# convert to the uniqued form
a_set, a_inv = np.unique1d(a, return_inverse=True)
b_set = np.unique1d(b)
# calculate matching elements
matches = np.setmea_set, b_set)
# invert the transformation
result = matches[a_inv]
print(result)
# [False  True False False  True  True False]

Modifier: Malheureusement, la méthode setmember1d dans numpy est vraiment inefficace. La méthode de recherche triée et affectée que vous avez proposée fonctionne plus rapidement, mais si vous pouvez affecter directement, vous pouvez également affecter directement le résultat et éviter de nombreuses copies inutiles. De plus, votre méthode échouera si b contient quelque chose qui ne soit pas dans a. Les éléments suivants corrigent ces erreurs:

result = np.zeros(a.shape, dtype=np.bool)
idxs = a.searchsorted(b)
idxs = idxs[np.where(idxs < a.shape[0])] # Filter out out of range values
idxs = idxs[np.where(a[idxs] == b)] # Filter out where there isn't an actual match
result[idxs] = True
print(result)

Mes repères montrent cela à 91 ° C contre 6,6 ms pour votre approche et 109 ms pour numpy setmember1d sur 1M élément a et 100 élément b.

ebresset, votre réponse ne fonctionnera pas si a est un sous-ensemble de b (et a et b sont triés). Sinon, la recherche triée retournera de faux index. Je devais faire quelque chose de similaire et le combiner avec votre code:

# Assume a and b are sorted
idxs = numpy.mod(b.searchsorted(a),len(b))
idxs = idxs[b[idxs]==a]
b[idxs] = numpy.nan
match = numpy.isnan(b)

Votre exemple implique un comportement de type ensemble, se souciant davantage de l'existence dans le tableau que d'avoir le bon élément au bon endroit. Numpy fait cela différemment avec ses tableaux et matrices mathématiques, il ne vous parlera que d'éléments à l'endroit exact. Pouvez-vous faire en sorte que cela fonctionne pour vous?

>>> import numpy
>>> a = numpy.array([1,2,3])
>>> b = numpy.array([1,3,3])
>>> a == b
array([ True, False,  True], dtype=bool)
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top