我在Matlab中有一个大小为Ksets
的矩阵Gx(l*N)
和一个大小为A
的矩阵MxN
。
Ksets
的每一行都可以分解为大小为l
的{{1}}子行。
让我用一个例子更好地解释。
1xN
在示例中:
clear
N=3;
l=4;
G=2;
M=5;
Ksets=[1 2 3 5 6 7 9 10 11 0 0 0;
13 14 15 1 2 3 21 22 23 1 1 1]; %Gx(l*N)
A=[1 2 3;
5 6 7;
21 22 23;
1 2 3;
0 0 0]; %MxN
的行1
由大小为Ksets
的{{1}}个子行组成:l
,1xN
,{ {1}},[1 2 3]
;
[5 6 7]
的行[9 10 11]
由大小为[0 0 0]
的{{1}}个子行组成:2
,Ksets
,{ {1}},l
。
我假设1xN
的每一行不包含相等的子行。
如果行[13 14 15]
等于[1 2 3]
子行之一,我希望您能帮助构建一个[21 22 23]
大小为[1 1 1]
的矩阵Ksets
-Response
行,否则为零。
继续上面的示例
GxM
这段代码可以满足我的要求:
Response(g,m)=1
我的代码由2个循环组成,这是不希望的,因为在我的实际算法中,A(m,:)
非常大。您有没有循环的建议吗?
答案 0 :(得分:1)
进行矢量化非常困难,尤其是如果您要比较的子集嵌入在每一行中。为了提高效率,可以将Ksets
更改为3D矩阵,其中每个切片包含格式化为2D矩阵的子集,其中每个子集都基于行。然后,您可以将ismember
与每行仅使用一个循环结合使用,并填充结果。
Ksets2 = permute(reshape(Ksets.', [N l G]), [2 1 3]);
Response = false(G, M);
for i = 1 : G
Response(i, :) = ismember(A, Ksets2(:,:,i), 'rows')';
end
第一条语句会重塑您的数据,使其成为3D矩阵,但是由于MATLAB的列主要处理,并且因为您的子集位于行主要,所以我们必须在重塑之前转置数据。但是,这导致每一列都在一个子集中,因此我们必须使用permute
操作独立地转置每个切片。
完成后,我们分配所需大小的矩阵,然后遍历Ksets
中的每一行(现已转换为子集的行)以产生所需的结果。
我们得到:
>> Response
Response =
2×5 logical array
1 1 0 1 1
1 0 1 1 0
答案 1 :(得分:1)
可以进行一些调整和尺寸置换:
Response = permute(any(all(bsxfun(@eq, reshape(Ksets.', N, [], G), permute(A, [2 3 4 1])), 1), 2), [3 4 1 2]);
其工作原理如下:
reshape(Ksets.', N, [], G)
将Ksets
整形为N
×l
×G
3D数组,以便每个子行现在都彼此分开。bsxfun(@eq, ..., permute(A, [2 3 4 1]))
创建一个N
×l
×G
×M
4D数组,并比较步骤3D数组中每个元素的结果1,每个值在A
中。all(..., 1)
测试每个子行(即第一维)的 all 个元素是否匹配。 any(...,2)
测试是否发生在原始行之一(即第二维)的 any 子行中。permute(..., [3 4 1 2])
除去前两个维(在步骤3中变为单例),得到所需的G
×M
结果。 (为此使用squeeze
是不安全的,因为如果使用G=1
,它将错误地删除三维尺寸。)