Pergunta

Alguém já vêm até este problema? Vamos dizer que você tem duas matrizes como o seguinte

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

Existe uma maneira de comparar o que elementos em um existir em b? Por exemplo,

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

Eu estou tentando evitar loops como levaria idades com milhões de elementos. Alguma ideia?

Felicidades

Foi útil?

Solução

Na verdade, há uma solução ainda mais simples do que qualquer um destes:

import numpy as np

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

c = np.in1d(a,b)

O c resultante é então:

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

Outras dicas

Use 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]

Note que np.intersect1d dá a resposta errada se a ou b têm elementos não exclusivos. Nesse caso de uso np.intersect1d_nu.

Há também np.setdiff1d, setxor1d, setmember1d e union1d. Vejo Exemplo Numpy Lista Com Doc

Obrigado por sua kaizer.se resposta. Não é bem o que eu estava procurando, mas com uma sugestão de um amigo e que você disse que eu vim com o seguinte.

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

É um pouco de um processo complicado, mas ele bate escrever laços ou usando tecer com loops.

Felicidades

Numpy tem uma numpy.setmember1d função set () que funciona em arrays e retornos classificados e uniqued exatamente a matriz booleana que você quer. Se os arrays dados não coincidem com os critérios que você precisa para converter para o formato do conjunto e inverta a transformação no resultado.

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]

Edit: Infelizmente o método setmember1d em numpy é realmente ineficiente. A pesquisa ordenados e método de atribuir-lhe proposto funciona mais rápido, mas se você pode atribuir diretamente assim como você pode atribuir diretamente para o resultado e evitar lotes de cópias desnecessárias. Também o seu método irá falhar se b contém nada que não seja em um. A seguir corrige esses erros:

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)

Os meus benchmarks mostram isso em 91us vs. 6.6ms para sua abordagem e 109ms para setmember1d numpy em 1M elemento de um e 100 elemento b.

ebresset, sua resposta não funcionará a menos um é um subconjunto de b (e a e b são classificados). Caso contrário, o searchsorted voltará índices falsos. Eu tinha que fazer algo semelhante, e que combina com o seu código:

# 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)

Seu exemplo implica definir-como comportamento, cuidar mais sobre existência na matriz do que ter o elemento certo no lugar certo. Numpy faz isso de forma diferente, com suas matrizes matemáticas e matrizes, ele irá dizer-lhe apenas cerca de itens no ponto certo exato. você pode fazer esse trabalho para você?

>>> import numpy
>>> a = numpy.array([1,2,3])
>>> b = numpy.array([1,3,3])
>>> a == b
array([ True, False,  True], dtype=bool)
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top