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

Tin*_*ria 5 arrays indexing performance matlab matrix

假设我有一个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
Run Code Online (Sandbox Code Playgroud)

和一个像这样的两个值的数组

E = [2,1]

e =

 2     1
Run Code Online (Sandbox Code Playgroud)

我需要知道t中哪一行有值1和2(即矩阵e的值).即,给定函数匹配(e,t),它应该返回满足该值的行号.

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

function [ faceindex ] = match(e,t)
c=ismember(t,e)
d=sum(c,2)
faceindex=find(d==2) 
end
Run Code Online (Sandbox Code Playgroud)

这就是它的工作原理:

匹配(E,T)

c =

 1     1     0
 0     1     0
 0     0     1
 1     0     0
 0     1     0
 1     0     0
 0     0     0
Run Code Online (Sandbox Code Playgroud)

d =

 2
 1
 1
 1
 1
 1
 0
Run Code Online (Sandbox Code Playgroud)

faceindex =

 1
Run Code Online (Sandbox Code Playgroud)

ans =

 1
Run Code Online (Sandbox Code Playgroud)

但是,我将它用于一个相当大的输入,它被调用了很多次,运行需要一段时间.Matlab的分析器向我展示了这个ismember函数的问题.有没有办法以更快的方式进行匹配?我愿意接受各种解决方案或提示.也许不需要使用的东西是成员进行检查.请注意,订单无关紧要.如果e是2,1 ......那行应该有1和2,并且可以按任何顺序排列.

Div*_*kar 8

你说,你需要找出行t有值1,并2在其(即矩阵的值e),并且您已经使用的代码- faceindex=find(d==2),所以我假设,如果e是说[1 2 7],我们必须去找找行te以任何顺序出现的元素的次数必须等于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));
Run Code Online (Sandbox Code Playgroud)

如果我只关注你的话而不是你的代码,那么让我引用你文本的一个重要部分 - "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));
Run Code Online (Sandbox Code Playgroud)

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

编辑1:在你的一条评论中,你说它总是只有两个值,e并且t永远不会有重复值,因此对于这种特定情况,可以使用两种方法.

方法1:

faceindex = find(sum( (t==e(1) | t==e(2)),2 )==2,1);
Run Code Online (Sandbox Code Playgroud)

方法2(对于非常大的数据量更好):

ind1 = find(any(t==e(1),2));
[r,c] = find(t(ind1,:)==e(2),1);
faceindex = ind1(r);
Run Code Online (Sandbox Code Playgroud)