将一个数组与矩阵中的每一行进行比较(其中列数可能不同)

5

假设我有一个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

我需要知道矩阵e中哪一行的值包含1和2(即矩阵e所代表的向量)。也就是说,给定一个函数match(e,t),它应该返回满足条件的行号。

我已经写了一个能够完成任务的函数match。

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

faceindex =

 1

答案 =

 1

然而,我将其用于相当大的输入,并且调用了多次,运行时间很长。Matlab的分析器显示问题出在ismember函数上。有没有更快的匹配方法?我可以接受任何解决方案或提示。也许有些方法不需要使用ismember进行检查。请注意,顺序并不重要。如果e是2,1...那么该行应该有1和2,并且可以以任何顺序排列。

1
e的大小是否会变化? - Ghaul
如果 e 变成 [1 2 7],那么 faceindex=find(d==2) 不会变成 faceindex=find(d==3) 吗? - Divakar
e的大小不会变化。它始终只有两个值,因此我只需要检查faceindex=find(d==2)。 - Tina T
2
@TinaMaria 如果t的一行有两个1和没有2,那么这应该计入faceindex吗? - Divakar
@Divakar: 我想我应该更具体地说明。如果我没有表述清楚,真的很抱歉。好吧,t永远不会有重复的值......所以它永远不会有两个1而没有2。 - Tina T
也许我也应该提一下...如果找到匹配项,那么t中只会有1行包含e的值。 - Tina T
2个回答

8
您需要识别在矩阵e中数值为1和2的行(即矩阵t的值)并采用代码“faceindex=find(d==2)”进行操作。因此,如果矩阵e为“[1 2 7]”,则我们必须查找在任意顺序下出现的元素的数量等于3(= e中元素的数量)的t中的行,然后尝试复制类似“faceindex=find(d==3)”的内容。我还假设e中的值是唯一的。使用这些条件,您可以尝试在通用情况下针对e和t采用bsxfun方法。
mat1 = bsxfun(@eq,t,permute(e,[3 1 2]));
faceindex = find(sum(reshape(mat1,size(t,1),[]),2)==numel(e));

如果我只看你的文字而不看你的代码,让我引用你的一段重要文字 - “我需要知道在t中哪一行有值1和2”。从这些话中可以推断出,你只想找到在t中每个元素至少出现一次的行数。因此,根据这个新假设和e中的唯一值,你可以尝试稍微修改我之前的代码。
mat1 = bsxfun(@eq,t,permute(e,[3 1 2]));
faceindex = find(all(squeeze(any(mat1,2)),2));

所以,请确定您真正想要的是什么,因为我没有看到您的代码表达了您的文本。
编辑1:在您的评论中,您说e中始终只有两个值,并且t永远不会有重复值,因此针对这种具体情况可以使用两种方法。
方法1:
faceindex = find(sum( (t==e(1) | t==e(2)),2 )==2,1);

方法二(适用于非常大的数据量):

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

非常有证据的答案 @Divakar 我也给你点赞。 - Sergio Haram
哈哈,我差点把那个读成“非常糟糕”:)再次感谢! - Divakar
@TinaMaria 太好了!请告诉我进展如何! - Divakar
1
@TinaMaria请查看Edit 1中的编辑代码,避免使用bsxfun,这可能会在更大的数据大小下成为瓶颈。 - Divakar
@Divakar:哇!加速真的很棒!非常感谢你的帮助。而且你说得对,bsxfun一定是瓶颈。 - Tina T
显示剩余3条评论

3

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

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

在这种情况下,矩阵A的范围从0到5。B是结果,如果A(i,j)等于1或2,则B(i,j)为1。您可以尝试调整B的参数,并且必须添加其他变量dfaceindex


这确实可以运行...但它的速度与我的匹配函数相同。不过还是谢谢你的帮助,我非常感激。 - Tina T

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