2009-12-16 20 views
64

¿Hay una función incorporada de MATLAB para averiguar si una matriz contiene un cierto valor? (al estilo de PHP in_array())Función para '¿la matriz contiene el valor X?'

+0

Para datos en coma flotante donde se desee una tolerancia, tenga en cuenta que la versión R2015a ha agregado una nueva funcionalidad para manejar esto con una sola función incorporada.Las soluciones aceptadas para datos de valores enteros son excelentes, pero para flotantes, vaya a [esta respuesta] (http://stackoverflow.com/a/28907857/2778484). Perdón por la autopromoción, pero es una gran adición a MATLAB después de años de preguntas de la gente. – chappjc

Respuesta

94

Muchas formas de hacerlo. ismember es lo primero que viene a la mente, ya que es una acción de membresía establecida que desea tomar. Por lo tanto,

X = primes(20); 
ismember([15 17],X) 
ans = 
     0 1 

Desde 15 no es primordial, pero 17 es, ismember ha hecho bien su trabajo aquí.

Por supuesto, encontrar (o cualquiera) también funcionará. Pero estos no están vectorizados en el sentido en que lo era el miembro. Podemos probar para ver si 15 está en el conjunto representado por X, pero para probar ambos números se tomará un ciclo, o pruebas sucesivas.

~isempty(find(X == 15)) 
~isempty(find(X == 17)) 

o,

any(X == 15) 
any(X == 17) 

Por último, me gustaría señalar que las pruebas para valores exactos son peligrosos si los números pueden ser verdaderos flotadores. Las pruebas contra los valores enteros que he mostrado son fáciles. Pero las pruebas contra los números de coma flotante generalmente deben emplear una tolerancia.

tol = 10*eps; 
any(abs(X - 3.1415926535897932384) <= tol) 
+2

El más rápido de los tres parece ser 'any'. Pero es posible que desee medir eso usted mismo (usando 'tic' y' toc'). – Lewistrick

+0

Para valores de coma flotante, si está utilizando al menos R2015a, simplemente use ['ismembertol'] (http://stackoverflow.com/a/28907857/2778484). – chappjc

10

que puede hacer:

A = randi(10, [3 4]);  %# a random matrix 
any(A(:)==5)    %# does A contain 5? 

Para hacer lo anterior en un vectorizado manera, el uso:

any(bsxfun(@eq, A(:), [5 7 11]) 

o como @woodchips sugiere:

ismember([5 7 11], A) 
+0

por qué estás usando [5 7 11] como argumento en ismember – Jordan

+1

@Jordan: la respuesta devuelta es una matriz lógica (verdadera/falsa) del mismo tamaño que el argumento, indicando si la matriz 'A' contiene cada uno de esos valores (por ejemplo, '[verdadero, verdadero, falso]' que significa 'A' contiene los valores' 5' y '7' pero no' 11'). – Amro

+0

ahora lo tengo, gracias – Jordan

3

Si es necesario comprobar si los elementos de un vector son en otro, la mejor solución es ismember como se menciona en las otras respuestas.

ismember([15 17],primes(20)) 

Sin embargo, cuando se trata de números de punto flotante, o simplemente quieren tener cerca los partidos (+ - 1000 es también posible), la mejor solución que he encontrado es el bastante eficiente File Exchange Submission: ismemberf

Se da una ejemplo muy práctico:

[tf, loc]=ismember(0.3, 0:0.1:1) % returns false 
[tf, loc]=ismemberf(0.3, 0:0.1:1) % returns true 

Aunque la tolerancia predeterminada normalmente debería ser suficiente, se le da más flexibilidad

ismemberf(9.99, 0:10:100) % returns false 
ismemberf(9.99, 0:10:100,'tol',0.05) % returns true 
2

Para datos de punto flotante, puede usar el nuevo ismembertol function, que calcula la membresía establecida con una tolerancia especificada. Es similar a la función ismemberf que se encuentra en el Intercambio de archivos, excepto que ahora está incorporada en MATLAB. Ejemplo:

>> pi_estimate = 3.14159; 
>> abs(pi_estimate - pi) 
ans = 
    5.3590e-08 
>> tol = 1e-7; 
>> ismembertol(pi,pi_estimate,tol) 
ans = 
    1 
Cuestiones relacionadas