【问题标题】:Finding whether the rows of a matrix in Matlab "fall" within the rows of another matrix查找 Matlab 中矩阵的行是否“落在”另一个矩阵的行中
【发布时间】:2019-02-06 16:27:31
【问题描述】:

我在 Matlab 中有一个大小为 Gx(l*N) 的矩阵 Ksets 和一个大小为 MxN 的矩阵 A

Ksets 的每一行都可以分解为l 大小为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

在示例中:

  • Ksets 的行1l 大小为1xN 的子行组成:[1 2 3][5 6 7][9 10 11][0 0 0]

  • Ksets 的行2l 大小为1xN 的子行组成:[13 14 15][1 2 3][21 22 23][1 1 1]

我假设Ksets 的每一行不包含相等的子行。

如果A(m,:) 的行等于Ksets(g,:)l 子行之一,则我希望您帮助构造一个大小为GxMResponse(g,m)=1 的矩阵Response,否则为零。

继续上面的例子

Response= [1 1 0 1 1; 
           1 0 1 1 0]; %GxM

这段代码做我想做的事:

Responsecorrectmy=zeros(G, M);
for x=1:G
    for c=1:l
        Responsecorrectmy(x,:)=Responsecorrectmy(x,:)+...
                               ismember(A,Ksets(x,(c-1)*N+1:c*N), 'rows').';
    end
end

我的代码由 2 个循环组成,这是不可取的,因为在我的真实算法中 G,l 很大。你有没有循环的建议?

【问题讨论】:

    标签: matlab


    【解决方案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
    

    【讨论】:

    • @LuisMendo ohhhhh 但它们都是真正的整数值,所以没关系! :D
    • @LuisMendo 很好。改变了它:P。
    • 你知道我的烦恼... :-)
    【解决方案2】:

    可以通过一些重塑和维度排列来完成:

    Response = permute(any(all(bsxfun(@eq, reshape(Ksets.', N, [], G), permute(A, [2 3 4 1])), 1), 2), [3 4 1 2]);
    

    它的工作原理如下:

    1. reshape(Ksets.', N, [], G)Ksets 重塑为 N×l×G 3D 数组,以便每个子行现在与其他子行分开。
    2. bsxfun(@eq, ..., permute(A, [2 3 4 1])) 创建一个N×l×G×M 4D 数组,其结果是将步骤 1 中的 3D 数组的每个元素与A 中的每个值进行比较。
    3. all(..., 1) 测试每个子行(即第一个维度)的元素是否匹配。 any(...,2) 测试这是否发生在原始行之一的 any 子行(即第二维)。
    4. permute(..., [3 4 1 2]) 删除前两个维度(在第 3 步中变为单例),得到所需的 G×M 结果。 (为此使用squeeze 是不安全的,因为如果G=1 会错误地删除第三维)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-27
      • 2015-12-28
      • 2012-10-11
      • 1970-01-01
      相关资源
      最近更新 更多