【问题标题】:Comparing an array with every row in a matrix (which may differ in column count)将数组与矩阵中的每一行进行比较(列数可能不同)
【发布时间】:2014-07-14 21:04:13
【问题描述】:

假设我有一个 7*3 矩阵 t。

>> t=[2,1,3;5,1,9;4,6,1;1,4,6;7,1,5;1,7,4;9,7,5]

t =

 2     1     3
 5     1     9
 4     6     1
 1     4     6
 7     1     5
 1     7     4
 9     7     5

还有一个像这样有两个值的数组

e=[2,1]

e =

 2     1

我需要知道 t 中哪一行的值是 1 和 2(即矩阵 e 的值)。 即,给定一个函数 match(e,t),它应该返回满足这一点的行号。

我写了一个函数匹配,它完成了这项工作。

function [ faceindex ] = match(e,t)
c=ismember(t,e)
d=sum(c,2)
faceindex=find(d==2) 
end

这就是它的工作原理:

匹配(e,t)

c =

 1     1     0
 0     1     0
 0     0     1
 1     0     0
 0     1     0
 1     0     0
 0     0     0

d =

 2
 1
 1
 1
 1
 1
 0

人脸指数 =

 1

ans =

 1

但是,我将它用于相当大的输入,并且它被调用了很多次,并且需要一段时间才能运行。 Matlab 的分析器向我展示了这个 ismember 函数的问题。有什么方法可以更快地进行匹配吗?我对任何类型的解决方案或提示持开放态度。也许不必使用 ismember 来进行检查。请注意,顺序无关紧要。如果 e 是 2,1...该行应该有 1 和 2 并且可以是任意顺序。

【问题讨论】:

  • e的大小有变化吗?
  • 如果e变成[1 2 7]faceindex=find(d==2)不会变成faceindex=find(d==3)吗?
  • 不,e 的大小没有变化。它总是只有两个值,所以我只检查 faceindex=find(d==2)
  • @TinaMaria 如果t 的一排有两个1s 而没有2 怎么办?这应该计入faceindex吗?
  • @Divakar :我想我应该更具体一些。如果我不够清楚,我真的很抱歉。好吧,t 永远不会有重复的值……所以它永远不会有两个 1,也不会有 2。

标签: arrays performance matlab matrix indexing


【解决方案1】:

嘿,不确定它是否更快,但是这样可以解决问题:

A = round(rand(10,4)*5)
B =zeros(size(A));
B(or(A==1,A==2)) = 1

这里 A 是本例中的矩阵,范围从 0 到 5。B 是结果,B(i,j) 是 1,因为 A(i,j) 等于 1 或 2。您可以使用 B 中的参数。必须添加您的其他变量dfaceindex

【讨论】:

  • 这确实有效......但它的运行速度与我的匹配功能相同。不过还是谢谢。非常感谢您的帮助。
【解决方案2】:

您说您需要识别t 中具有12 值的行(即矩阵e 的值)并且您使用了代码-faceindex=find(d==2) ,所以我假设如果e[1 2 7],我们必须在t 中查找行,其中e 的元素以任何顺序出现的次数必须等于3(= number of elements in e)因此我们必须尝试复制类似 -faceindex=find(d==3) 的内容。我还假设e 中的值是唯一值。

有了这些要使用的条件,您可以尝试这种bsxfun 方法来处理et 的一般情况-

mat1 = bsxfun(@eq,t,permute(e,[3 1 2]));
faceindex = find(sum(reshape(mat1,size(t,1),[]),2)==numel(e));

如果我只关注你的文字而不是你的代码,让我引用你文本的重要部分 - "I need to know which row in t has the values 1 and 2 in it"。从这些话中,可以推断您只想找出t 的行号,其中e 中的每个元素至少出现一次。因此,遵循这个新假设并且 e 中的值是唯一值,您可以尝试对我之前的代码进行稍微修改的版本 -

mat1 = bsxfun(@eq,t,permute(e,[3 1 2]));
faceindex = find(all(squeeze(any(mat1,2)),2));

所以,请确定你真正想要的是什么,因为我没有看到你的代码为你的文字说话。

编辑 1: 在您的一个 cmets 中,您说 e 中始终只有两个值,并且 t 永远不会有重复值,因此对于这种特定情况,有两种方法可以使用。

方法一:

faceindex = find(sum( (t==e(1) | t==e(2)),2 )==2,1);

方法 2(更适合非常大的数据量):

ind1 = find(any(t==e(1),2));
[r,c] = find(t(ind1,:)==e(2),1);
faceindex = ind1(r);

【讨论】:

  • 我也给@Divakar +1 提供了很好的答案。
  • @SergioHaram 哈哈,我差点把它读成“非常可怜”:) 再次感谢!!
  • 刚刚试了一下....谢谢....我已经尝试过中等大小的输入,似乎执行时间减半。太棒了!
  • 我会看看更大的物体会发生什么。谢谢@Divakar!
  • @TinaMaria 查看Edit 1 中的编辑代码,避免bsxfun,这可能是较大数据量的瓶颈。
猜你喜欢
  • 2019-05-23
  • 1970-01-01
  • 2017-08-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
  • 2019-03-14
  • 1970-01-01
相关资源
最近更新 更多