矩阵中是否包含数值X的函数?

73

是否有内置的MATLAB函数可以查找矩阵中是否包含某个值? (类似于PHP的in_array()


对于浮点数据,如果需要一定的容差,请注意 R2015a版本增加了一个新功能,可以用一个内置函数进行处理。虽然针对整数值数据的解决方案已经很好了,但是对于浮点数,请参考这个答案。非常抱歉有自我宣传之嫌,但在经过多年人们的建议后,这是 MATLAB 中的一个重大补充。 - chappjc
4个回答

100

有很多方法可以做到这一点。ismember 是我首先想到的,因为它是您希望执行的集合成员操作。因此

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

由于 15 不是质数,但 17 是,ismember 在这里表现得非常出色。

当然,find(或任何)也可以工作。 但从向量化的角度来看,这些函数并不能像 ismember 那样。我们可以测试是否在 X 表示的集合中存在 15,但要测试这两个数字将需要循环或连续的测试。

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

或者,

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

最后,我要指出,如果数字可能是真正的浮点数,那么对于精确值的测试是有风险的。如我所示,针对整数值的测试很容易。但是,针对浮点数的测试通常应该使用公差。

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

2
三者中最快的似乎是“any”。但你可能想要自己测量一下(使用“tic”和“toc”)。 - Lewistrick
对于浮点数值,如果你使用的是 R2015a 或更高版本,则可以直接使用 ismembertol - chappjc

11

你可以这样做:

A = randi(10, [3 4]);      %# a random matrix
any( A(:)==5 )             %# does A contain 5?
为了以一种向量化的方式完成上述操作,请使用:
any( bsxfun(@eq, A(:), [5 7 11] )

或者如@woodchips建议的那样:

ismember([5 7 11], A)

为什么在ismember函数中使用[5 7 11]作为参数? - Jordan
1
@Jordan:返回的答案是一个逻辑数组(true/false),大小与参数相同,指示矩阵A是否包含这些值(例如[true, true, false]表示A包含值57但不包含11)。 - Amro
1
@AnderBiguri:这里有一些测试可以运行进行比较:https://gist.github.com/amroamroamro/e66ac6a88b0692d995fd - Amro

3
如果你需要检查一个向量中的元素是否存在于另一个向量中,最好的解决方法是使用在其他答案中提到的 ismember
ismember([15 17],primes(20))

然而,当您处理浮点数或只想要接近的匹配(+-1000也可能)时,我发现最好的解决方案是相当有效的File Exchange Submission:ismemberf
它提供了一个非常实用的例子:
[tf, loc]=ismember(0.3, 0:0.1:1) % returns false 
[tf, loc]=ismemberf(0.3, 0:0.1:1) % returns true

虽然默认公差通常已足够,但这样做可以让您更加灵活。

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

2

对于浮点数据,您可以使用新的ismembertol函数,该函数计算具有指定容差的集合成员。这类似于文件交换中找到的ismemberf函数,但现在已内置于MATLAB中。例如:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接