我在Matlab中有一个大小为index
的矩阵GxN
和一个大小为A
的矩阵MxN
。
在提出问题之前,让我提供一个例子。
clear
N=3;
G=2;
M=5;
index=[1 2 3;
13 14 15]; %GxN
A=[1 2 3;
5 6 7;
21 22 23;
1 2 3;
13 14 15]; %MxN
如果行Response
等于GxM
,如果行Response(g,m)=1
等于A(m,:)
,我想请您帮忙用index(g,:)
构造大小为Response= [1 0 0 1 0;
0 0 0 0 1]; %GxM
的矩阵Response=permute(any(all(bsxfun(@eq, reshape(index.', N, [], G), permute(A, [2 3 4 1])), 1), 2), [3 4 1 2]);
。
继续上面的示例
N=19, M=500, G=524288
这段代码可以满足我的要求(取自previous question of mine-只是为了澄清:当前的问题有所不同)
SSRS
但是,对于我的实际矩阵大小(2008R2
),该命令非常慢。我知道我将无法获得巨大的速度,但是对此有任何改进的建议。
答案 0 :(得分:7)
MATLAB具有working with sets的多种功能,包括setdiff
,intersect
,union
等。在这种情况下,您可以使用ismember
函数:
[~, Loc] = ismember(A,index,'rows');
哪个给:
Loc =
1
0
0
1
2
Response
的构造如下:
Response = (1:size(index,1) == Loc).';
Response =
2×5 logical array
1 0 0 1 0
0 0 0 0 1
答案 1 :(得分:7)
如果您具有统计信息工具箱:
Response = ~(pdist2(index, A));
或:
Response = ~(pdist2(index, A, 'hamming'));
之所以可行,是因为pdist2
计算每对行之间的距离。相等的行的距离为0
。逻辑否定~
为这些行对给出1
,否则为0
。
这种方法在我的机器上更快:
[~,~,u] = unique([index; A], 'rows');
Response = bsxfun(@eq, u(1:G), u(G+1:end).');
通过将行简化为唯一的整数标签(使用unique
的第三个输出),然后比较后者而不是前者来进行工作。
对于您的尺寸值,这在我的计算机上大约需要1秒钟:
clear
N = 19; M = 500; G = 524288;
index = randi(5,G,N); A = randi(5,M,N);
tic
[~,~,u] = unique([index; A], 'rows');
Response = bsxfun(@eq, u(1:G), u(G+1:end).');
toc
给予
Elapsed time is 1.081043 seconds.
答案 2 :(得分:3)
您可以reshape
矩阵,以便每一行都位于第三维。然后,我们可以使用隐式扩展(对于R2016b或更早版本,请参见bsxfun
)来实现所有元素的相等性,并使用all
在行上进行聚合(即,如果给定行的所有值都不相等,则为false)。>
Response = all( reshape( index, [], 1, size(index,2) ) == reshape( A, 1, [], size(A,2) ), 3 );
您甚至可以通过在另一维度上使用all
来避免某些重塑,但是我可以通过这种方式将其形象化。