用Matlab进行匹配
我想去用Matlab进行匹配,matlab,Matlab,我想去 A =[1;2;3;4;5] B= [10 1 ;11 2;19 5] 也就是说,如果A中的某个东西在B中不存在,那么D的第2列应该是-9 如果A中的某个东西存在于B:,2中,我想把B的第1列的对应行放在D的第2列中 我知道如何混合使用ismember和for以及if。但我需要一个更优雅的方法,它不用于加速。首先创建一个临时矩阵: D = [1 10 ;2 11; 3 -9; 4 -9; 5 19] 然后使用find获得第一行索引,该索引与tmp第二列中a的元素相匹配。始终存在设计匹
A =[1;2;3;4;5]
B= [10 1 ;11 2;19 5]
也就是说,如果A中的某个东西在B中不存在,那么D的第2列应该是-9
如果A中的某个东西存在于B:,2中,我想把B的第1列的对应行放在D的第2列中
我知道如何混合使用ismember和for以及if。但我需要一个更优雅的方法,它不用于加速。首先创建一个临时矩阵:
D = [1 10 ;2 11; 3 -9; 4 -9; 5 19]
然后使用find获得第一行索引,该索引与tmp第二列中a的元素相匹配。始终存在设计匹配
tmp=[B; -9*ones(size(A(~ismember(A,B)))), A(~ismember(A,B))]
tmp =
10 1
11 2
19 5
-9 3
-9 4
作为第二步的替代方案,您可以简单地根据tmp的第二列对其进行排序:
D=[A, arrayfun(@(x) tmp(find(tmp(:,2)==x,1,'first'),1),A)];
D =
1 10
2 11
3 -9
4 -9
5 19
我不确定该解决方案的效率如何,但它避免了使用任何循环,因此至少它是一个起点:
[~,I]=sort(tmp(:,2));
D=[tmp(I,2), tmp(I,1)]
D =
1 10
2 11
3 -9
4 -9
5 19
您可以提前分配矩阵,以节省以后的时间。在MATLAB中,动态构建矩阵的速度非常慢。ismember调用返回true false向量tf,显示A的哪些元素对应于B中的某个元素,以及它们对应于idx中的内容的相关索引。idx的问题是,当ft为零时,它包含一个零,这就是为什么我们有行idxidx==0=[];清除这些零。最后,在本例中,findtf用于获取与D的目标行上的匹配相关联的索引,我们将这些索引处的值设置为我们想要的B中的对应值。除非我遗漏了什么或者a不是索引向量,否则这实际上要简单得多,并且根本不需要ismember或find,直接索引:
D = [A -9*ones(size(A))]; % initialize your result
[tf, idx] = ismember(A, B(:,2)); % get indices of matching elements
idx(idx==0) = []; % trim the zeros
D(find(tf),2) = B(idx,1); % set the matching entries in D to the appropriate entries in B
disp(E)
在你的例子中,矩阵给出了
D = [A zeros(length(A),1)-9];
D(B(:,2),2) = B(:,1)
对于一般A:
这给
A =[1;2;3;4;6]; % Note change in A
B= [10 1 ;11 2;19 5];
[aux, where] = ismember(A,B(:,2));
b_where = find(where>0);
D = [(1:length(A)).' repmat(-9,length(A),1)];
D(b_where,2) = B(where(b_where),1);
@体素八叉树我不同意。MATLAB使用。@voxeloctree我认为许多内部用于循环的内置MATLAB函数都是在编译它们的C代码中使用的,因此比直接在MATLAB中使用for循环更有效。这是因为MATLAB是一种解释语言,每次运行时都必须编译成处理器可以处理的东西。这些内置函数已经针对处理器进行了优化,而MATLAB for循环可能不是。@voxeloctree许多内置函数在底层C代码中使用循环,但是MATLAB中的for循环非常慢,应该避免。更不用说while循环了。cellfun和arrayfun比手动循环快得多是有原因的。此外,内置函数能够使用SIMD指令,Matlab代码不能。简言之,你的建议不好。@kevlar也许我有点错,但GPU/并行计算不是一般的编程,而是一个完全不同的野兽。即使在并行计算中,您也偶尔需要循环@工程师:好的方面,@KitsuneYMG全面思考问题,用不好的方式解决问题,然后尝试优化它,这绝不是坏建议,但鉴于OP已经这样做了,也许你是对的。我会编辑我的评论,但鉴于你们已经这么做了,我认为没必要这么做:好吧,好吧,伙计们,我会删除我的坏建议。OP可能正在使用MATLAB实现这些高级功能。太棒了!我讨厌把事情搞得太复杂。是的,举个例子就行了。但是,当A不能用作索引时,这将不起作用solution@Luis_Mendo非常感谢。但是你有什么理由改变主意吗?我这样问是为了更好地理解你的代码。再次感谢。我更改输入A的唯一原因是,即使A的形式不是[1 2 3…]即连续数字,我的解决方案仍然有效。如果你的A总是有这样的形式,你可以使用@horchler的解决方案,这更简单。现在我的声誉达到了一定程度,我可以投票给你:你的解决方案甚至对A=[2;1;8;4;7]和B=[10 1;11 2;19 7]都有效。谢谢。当B的索引在第一列,并且有更多的列时,这就有效了。D=[A 99999999*onessizeA,1,sizeB,2-1];%初始化结果[tf,idx]=ismemberA,B:,1;%获取匹配元素的索引idxidx==0=[];%修剪零Dfindtf,2:sizeB,2=Bidx,2:end;
A =[1;2;3;4;6]; % Note change in A
B= [10 1 ;11 2;19 5];
[aux, where] = ismember(A,B(:,2));
b_where = find(where>0);
D = [(1:length(A)).' repmat(-9,length(A),1)];
D(b_where,2) = B(where(b_where),1);
D = [ 1 10
2 11
3 -9
4 -9
5 -9 ]